I recently ran into a perplexing issue with some of my React based projects on Glitch. They would stall in the startup stage (package.json -> scripts -> start
), and eventually the live view would simply display an error in the form of:
failed to start application on PROJECT_NAME.glitch.me
This is most likely because your project has a code error.
Check your project logs, fix the error and try again.
Normally, I would agree with the error message that in all probability, the issue is probably with my code. However, this was happening with old repos, that had worked before, and the final straw was that it happened 100% of the time with a brand new blank React project scaffolded with Create-React-App.
Click here to jump right to the solution. Read on for full details.
The Issue
A quick search to see if anyone else was experiencing this issue brought me to two posts on the Glitch forums:
- “Can’t play with create react app on glitch”
- “
create-react-app
project never leaves”Starting” state”
Both of those threads point to the post “create-react-app and express together on Glitch” as being the best answer to this issue.
Although the post mentioned above does indeed contain a solution, complete with working Glitch project that you can clone / remix, I personally find the solution reached to be rather complicated and overall something that founds like a substantial workaround. Not to mention, it starts to become pretty far removed from the default CRA starter…
However, after some digging, I actually found a far simpler solution. It looks like the crux of the issue might have less to do with conflicting ports, and more to do with CRA’s (and React-Scripts) reliance on having an interactive shell available (tty
+ open stdin
).
There are tons of posts that indicate this could be the issue, including the following: – CRA GH: Issue #8688 (“Fails to start in Docker”) – S/O: React App exiting in docker container with exit code 0
I can’t find Glitch’s Docker config to see if they have TTY turned off, but it certainly would line up with the results I’m seeing. And the fact that this appears to be a newer change to CRA, which would explain why repos using older versions of react-scripts still work.
The Fix
Thankfully, someone on the thread for issue #8688 identified an easier solution than rolling back CRA scripts or changing the Docker config (which would be impossible on Glitch). In this comment, they mention using CI=true
to set the environmental variable CI
to be true.
To clarify, CI
stands for “continuous integration”, and in the context of React, this is important for automated testing. Setting CI=true
is meant to be used when running tests, for a proper setup. However, it also makes sense that it would work for the tty
issue, since setting CI=true
likely also forces React into a non-interactive mode that does not require an interactive shell, since many CI pipelines also lack an interactive shell for executing automated tests (reasonable).
The Fix – Quick Package.json Edit
If you need to set CI=true
for Glitch, that could be as easy as changing your start entry from react-scripts start
to CI=true react-scripts start
. However, that is going to disable the interactive mode of CRA everwhere, not just on Glitch!
If you want to only apply the fix only on Glitch, there is another trick up my sleeve for you!
You can take advantage of the fact that Glitch sets certain environmental variables within it’s own system. For example, this will work right now to only apply the CI
fix on Glitch:
{
"scripts": {
"start": "echo $PROJECT_REMIX_CHAIN | grep -E \".+\" && CI=true react-scripts start || react-scripts start"
}
}
An even easier fix is to use a tool I built that takes care of checking the environment for you – “detect-is-on-glitch”. With that tool, the entire command above could be shortened to:
{
"scripts": {
"start": "isglitch && CI=true react-scripts start || react-scripts start"
}
}
isglitch
is another way to calldetect-is-on-glitch
Plus, my tool scans multiple environmental values, works across multiple OSes, and I’ll update it if Glitch makes changes that stop certain variables from being exposed.
WARNING: the
CI=true
syntax will fail on Windows – see section below for details.
Cross-Env Considerations
WARNING: The
CI=true
is the Unix / bash syntax for setting environmental variables.
If you want a way to set environmental values across all operating systems, you will need to add cross-env
as a dependency, and then change CI=true
to cross-env CI=true
.
In addition, for reading environmental variables in a cross-env nature, you can use a quick hack of node -p "process.env.VARIABLE_TO_CHECK"
. If you want to ensure you receive either the value itself or an empty string (but not undefined), use node -p "process.env.VARIABLE_TO_CHECK || ''"
.
Using glitch.json
If you are reluctant to edit your package.json to accommodate Glitch, an alternative solution can be to use glitch.json
to tell Glitch to use the special start command. However, this takes some extra configuring; you would have to find the global path of NPM (or pnpm
for Glitch, likely), setup a shell script to call react-scripts with CI=true, and then point glitch.json
at the shell script.
If you really want to go down that route, make sure you review my Glitch guide, and in particular, the Troubleshooting section.
Demo
I put together a quick demo / starter repo, generated from Create-React-App, and configured with my fix for Glitch. Source code is on GitHub, and the live Glitch is here.
Conflicting Ports
Even if the above does not work for you, and you are convinced it is an issue with conflicting ports, you don’t have to roll your own proxy code like they did in that linked post. There is actually a built-in feature in react-scripts
that will take care of it for you; all you have to do is declare the proxy destination in package.json -> proxy
field. This will proxy all unknown (e.g. non-static files and routes) to the defined proxy.
For example, to proxy all non-static requests to port 3001
, use:
{
"proxy": "http://localhost:3001"
}
You can find the docs on this feature here, and Dave Ceddia has an excellent writeup on using it with CRA + Express.
NOTE: You can also use environmental variables to change the port dev server listens on (with
PORT=#
) and the host it is bound to (withHOST=___
). Refer to the advanced configuration docs for details.