Blog
Floxifying a Project Repo, Part 2
Steve Swoyer | 23 January 2025

It’s fairly straightforward to migrate orchestrated dev container runtimes so they can be defined, managed, and shared as portable, reproducible Flox environments.
But what about code? Like, for example, projects in GitHub, GitLab, AWS CodeCommit, or other repos?
Is it possible to migrate—or “Floxify”—public-facing projects so that they, too, can be managed and shared as portable, reproducible Flox environments? Absolutely!
In this walk-through, we’ll explore two powerful projects, node-red and n8n, and show you how to Floxify and run them anywhere.
Spoiler alert: there’s almost no heavy-lifting involved.
Let’s get down to the nitty gritty.
Floxifying node-red
Let’s start with node-red
, a flow-based development tool for wiring together hardware devices, APIs, and services using a browser-based visual editor. First we’ll make a local copy of the GitHub repo.
git clone https://github.com/node-red/node-red
Then we’ll cd
into the node-red
repo directory and run flox init
. Like git init
, this initializes a new Flox environment in the current directory, creating the .flox
folder and a few required sub-folders.
When you run flox init
in a folder containing a package.json
, Flox’s built-in automation kicks in:
⠧ Resolving packages from catalog
Flox detected a package.json compatible with node 22.11.0
Flox can add the following to your environment:
* nodejs 22.11.0 with npm bundled
* An npm installation hook
! Would you like Flox to apply this suggestion?
You can always change the environment's manifest with 'flox edit'
> Yes
No
Show suggested modifications
[Use '--auto-setup' to apply Flox recommendations in the future.]
When I choose Yes
, Flox does the following:
- Installs the version of Node.js defined in
package.json
; - Runs
npm install
to install the packages defined inpackage.json
.
Next I’ll activate the environment (flox activate
) and build node-red
:
npm run build
> [email protected] build
> grunt build
Running "clean:build" (clean) task
>> 0 paths cleaned.
Running "jsonlint:messages" (jsonlint) task
>> 50 files lint free.
Running "jsonlint:keymaps" (jsonlint) task
>> 1 file lint free.
Running "concat:build" (concat) task
Running "concat:vendor" (concat) task
Running "copy:build" (copy) task
Created 21 directories, copied 306 files
Running "uglify:build" (uglify) task
>> 4 files created 2.55 MB → 963 kB
Running "sass:build" (sass) task
Running "attachCopyright:js" (attachCopyright) task
Attached copyright to packages/node_modules/@node-red/editor-client/public/red/red.min.js
Attached copyright to packages/node_modules/@node-red/editor-client/public/red/main.min.js
Running "attachCopyright:css" (attachCopyright) task
Attached copyright to packages/node_modules/@node-red/editor-client/public/red/style.min.css
Done.
Success! Now let’s kickstart a local instance of node-red
:
npm start
> [email protected] start
> node packages/node_modules/node-red/red.js
22 Jan 15:56:25 - [info]
Welcome to Node-RED
===================
22 Jan 15:56:25 - [info] Node-RED version: v4.0.8
22 Jan 15:56:25 - [info] Node.js version: v22.11.0
22 Jan 15:56:25 - [info] Linux 6.12.9-amd64 x64 LE
22 Jan 15:56:25 - [info] Loading palette nodes
22 Jan 15:56:25 - [info] Settings file : /home/daedalus/.node-red/settings.js
22 Jan 15:56:25 - [info] Context store : 'default' [module=memory]
22 Jan 15:56:25 - [info] User directory : /home/daedalus/.node-red
22 Jan 15:56:25 - [warn] Projects disabled : editorTheme.projects.enabled=false
22 Jan 15:56:25 - [info] Flows file : /home/daedalus/.node-red/flows.json
22 Jan 15:56:25 - [info] Creating new flow file
22 Jan 15:56:26 - [warn]
---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.
If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.
You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------
22 Jan 15:56:26 - [info] Server now running at http://127.0.0.1:1880/
22 Jan 15:56:26 - [warn] Encrypted credentials not found
22 Jan 15:56:26 - [info] Starting flows
22 Jan 15:56:26 - [info] Started flows
It looks as if it’s running, but is it? Let’s confirm by bringing it up in our web browser.
Yes. Yes it is!
Creating a managed shared node-red environment
Rather than replicating the steps outlined above, you can just pull and run the Flox node-red
example environment I built for this walk-through. The logic I built into this environment automates these steps.
Just create a project directory (e.g., node-red
), change into it, and run...
flox pull --copy barstoolbluz/node-red
...to create a persistent local copy of my prototpye environment. If you just want to take it for a test drive, you can use one of Flox’s coolest features, remote activation, to run a temporary session that doesn’t persist. Say you’re in a directory with dozens of JSON data files that you need to process and transform before sending to an API. You can remotely activate my Flox node-red
environment to do this!
flox activate -s -r barstoolbluz/node-red
You don’t need to be in a dedicated project directory when you remotely activate an environment. This is perfect when you’re working on a project and need a tool or service that otherwise isn’t available to you.
The -s
switch tells Flox to start any services defined for the environment, while the -r
switch tells Flox to activate my environment remotely. As for barstoolbluz/node-red
, this designates two things:
- My FloxHub user handle (
barstoolbluz
); - The name of the environment (
node-red
).
My node-red
environment should bootstrap itself. Let me share just a snippet of the logic I built into it:
on-activate = '''
REPO_URL="https://github.com/node-red/node-red.git"
REPO_DIR="$FLOX_ENV_CACHE/node-red"
ran_any_task=false
clone_repo() {
[ -d "$REPO_DIR" ] && [ -f "$REPO_DIR/package.json" ] && return
gum confirm "Would you like to clone the repo $REPO_URL?" && git clone "$REPO_URL" "$REPO_DIR" && ran_any_task=true
}
check_npm_install() {
[ -d "$REPO_DIR/node_modules" ] && return
npm install --prefix "$REPO_DIR" && ran_any_task=true
}
check_npm_build() {
[ -d "$REPO_DIR/packages/node_modules/@node-red/editor-client/public" ] && return
npm run build --prefix "$REPO_DIR" && ran_any_task=true
}
print_post_run_message() {
$ran_any_task && echo "If this is your first time setting up this environment, you may need to start Node-RED manually. Use the alias \`node-red\` to do so."
}
clone_repo
check_npm_install
check_npm_build
print_post_run_message
This logic checks if the node-red
repo has been cloned; if dependencies are installed; and/or if node-red
is built. Depending on conditions, it either skips these steps, or runs them. If and only if it performs any of these steps, it prompts the user to start node-red
manually using a defined alias. I created this last check because flox activate -s
cannot start the node-red
service if node-red
itself hasn’t been built!
Floxifying n8n
We’ll take a different approach in Floxifying n8n
, a no-less-neat open-source workflow automation tool that’s also useful for connecting APIs, services, and data. This time, we won’t clone the n8n
GitHub repo. Instead, we’ll install Node.js into a Flox project environment and define an activation hook that installs n8n
.
Before we can do that, we’ll need to create a project folder, cd
into it, and initialize a Flox environment:
mkdir n8n && cd n8n && flox init
Now we can install Node.js. We can either do this imperatively, like so…
flox install nodejs
Or run flox edit
and do this declaratively. This opens Flox’s default configuration artifact, manifest.toml
in either (a) a vi
-like terminal editor or (b) the editor specified by the EDITOR
environment variable. The manifest.toml
file lives in the path .flox/env/
inside a Flox environment.
Here’s what this looks like:
[install]
nodejs.pkg-path = "nodejs"
Either approach installs the latest version of Node.js (v22.12.0) in a fresh environment. We can also install a specific recent version, like v20.15.1, or historical versions going back several years, like, say, v14.17.0. The n8n
maintainers say Node.js version 18.x releases are the most compatible, so let’s install one of those.
We can do this imperatively, by running flox install [email protected]
, or declaratively, like so:
[install]
nodejs.pkg-path = "nodejs"
nodejs.version = "18.18.2"
With Node.js defined in our environment, let’s create some logic to install and run n8n
.
To their credit, the folks behind n8n
have made this shockingly simple:
[hook]
on-activate = '''
npx n8n
'''
That’s it. This activation hook tells npx
to download (if required), build (idem), and run n8n
. When we kickstart this environment by running flox activate
, this puts us in an isolated subshell and runs our hook.
✅ You are now using the environment 'n8n'.
To stop using this environment, type 'exit'
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
Yes (y) let’s do proceed. This will take a few minutes because npx
has to download a lot of stuff. Once it’s finished (and after it’s printed a few dozen status messages to the terminal) we’ll see the following:
Version: 1.75.2
Editor is now accessible via:
http://localhost:5678/
Press "o" to open in Browser.
Pressing o
does indeed open n8n
in a Web browser. (This even worked in Windows and WSL2.) In the screenshot below, you can see that, yes, I did give them a valid-ish email address:
I’ve created an n8n
example environment that automates this stuff. You can either pull a permanent local copy…
flox pull --copy barstoolbluz/n8n
...or remotely activate it:
flox activate -r barstoolbluz/n8n
Your Repo: Everywhere you want it to be
It’s fairly easy to Floxify almost any existing project, including a public GitHub repo. And it’s just as easy to “decorate” that project—e.g., by adding automations that terraform or bootstrap the environment.
For example, in the Flox node-red
prototype, just a few lines of logic are enough to automate the following:
- Prompt the user (Yes/No) to clone the
code-red
GitHub repo; - Check whether the required
npm
packages are installed; - Check whether
npm run build
has been executed.
When you git push
or flox push
this environment, the users you share it with enjoy a turn-key experience.
If you’re intrigued by what you’ve seen, download Flox and take it for a test drive.
Try Floxifying one of your own repos and sharing it with friends or co-workers. Granted, not all projects are going to be as easy or straightforward. If you get stuck, let us know, either by popping into our Discourse forum or joining our community Slack. Some of us (guilty!) usually have nothing better to do, so chances are you’ll get a quick response!