Skip to main content

Installation

FluidCAD ships as a desktop app for Windows, Linux and macOS, as an npm package for running it from a Node.js project in your browser, and as a Docker image for keeping your projects on a server. Pick the download for your system below, or skip to the npm installation if you prefer to work from a terminal.

Models are .part.js files (parts) and .assembly.js files (assemblies), written by the viewport as you work.

The links below point at the current release, FluidCAD 0.0.48; every build is also on the GitHub releases page. The app updates itself from there afterwards: it checks quietly in the background and installs the next version when you quit.

Windows​

Run the installer and follow the prompts. The installer is not code-signed, so Windows SmartScreen shows Windows protected your PC on first launch; choose More info → Run anyway.

Linux​

For the AppImage, mark it executable (chmod +x FluidCAD-*.AppImage) and run it. For the .deb, install it with sudo apt install ./FluidCAD-*.deb. The AppImage updates itself; the .deb is updated by installing the next release's package.

macOS​

Open the disk image and drag FluidCAD into Applications. The build is signed and notarized, so it opens without a Gatekeeper prompt.

npm installation​

If you would rather run FluidCAD from a terminal and model in your browser, run it with npx: on its own for the start screen, or inside a project to open just that one.

Prerequisites​

  • Node.js version 24 or higher
  • npm (comes with Node.js)

The start screen​

npx fluidcad

opens the start screen in your browser, the same one the desktop app shows: your recent projects, New Project, Open Project, and the engine each project runs on. Each project opens in a tab of its own. Leave the command running while you work; Ctrl+C stops FluidCAD and every project it opened. See fluidcad in the CLI Reference.

Create a new project​

To set a project up from the terminal instead:

mkdir my-hinge && cd my-hinge
npm i fluidcad
npx fluidcad init
npx fluidcad serve

init creates a project with the following structure:

my-hinge/
├── package.json
├── jsconfig.json
├── fluidcad.json ← project configuration (engine pin, unit)
├── init.js ← required project entry point
└── part1.part.js ← your first part, empty

serve starts the FluidCAD server and opens the viewport in your browser. Leave it running while you model; press Ctrl+C to stop it.

FlagDescriptionDefault
-w, --workspace <path>Path to your projectCurrent directory
-p, --port <port>Server port — if it's already taken, the next free one is used3100
--no-openDon't launch a browser — for CI and remote sessionsopens by default

To run from elsewhere, point -w at your project: npx fluidcad serve -w ./my-app.

fluidcad.json records which FluidCAD version the project was authored against and, optionally, its default length unit. See Project configuration.

note

FluidCAD model files use the .part.js extension (assemblies use .assembly.js). The viewer only picks up files with this naming convention.

note

FluidCAD is installed per-project and run with npx fluidcad …; a global install (npm install -g fluidcad) is not supported. The engine and your editor's type hints both resolve from the project's node_modules, so the package must live there. If you see Cannot find module 'fluidcad' imported from …, run npm i fluidcad inside the project.

The init.js file​

Every FluidCAD project must have an init.js file at its root. It initializes the engine and must be present before any .part.js file can run:

import { init } from 'fluidcad';

export default await init();

Do not modify this file — it is generated by npx fluidcad init and is required for the viewer to work. Project configuration covers what it does and what else lives in the project folder.

The starter file​

Open part1.part.js. This is the file that was generated for you, and it is the part the viewport opens on when the server starts:

import { part } from 'fluidcad/core';

export const part1 = part('Part 1', () => {
});

part('Part 1', () => { ... }) declares a named part and exports it as part1. Everything inside the callback builds that part, and the export is what an assembly would later insert(). The callback is empty, so the viewport is too: every sketch and feature you add, from the toolbar or in code, lands inside it and becomes a row in the History panel.

Rename the file and the part to what you are building; Parts covers the convention.

Beyond serve​

The same CLI writes STEP, STL, and PNG files without opening the UI, and runs the MCP server that lets AI agents drive your workspace:

npx fluidcad export step # every shape → <entry>.step
npx fluidcad export png --view front --open

See the CLI Reference for every command and flag, or run npx fluidcad --help.

Docker​

To keep your projects in one place, on a server or on a machine others on your network use, run the start screen in a container. The image is ghcr.io/fluid-cad/fluidcad, built for x64 and ARM64 and tagged with each release's version (0.0.47) and latest:

docker pull ghcr.io/fluid-cad/fluidcad:latest

The container runs the start screen with a projects folder at /app/projects: the start screen lists every project in it, and New Project creates the next one there. Mount a folder of your own on it so the projects outlive the container. On Linux that folder has to be writable by uid 1000, the user the container runs as (sudo chown 1000:1000 projects).

The second mount, /home/node/.fluidcad, keeps what FluidCAD remembers between runs: engines downloaded for projects pinned to another FluidCAD version, recent projects and previews.

On your own machine​

mkdir projects
docker run -d --name fluidcad \
-p 127.0.0.1:3100:3100 \
-e FLUIDCAD_ALLOWED_HOSTS=localhost \
-v "$PWD/projects:/app/projects" \
-v fluidcad-home:/home/node/.fluidcad \
ghcr.io/fluid-cad/fluidcad:latest

docker logs fluidcad

The logs print a sign-in link, http://localhost:3100/?token=…. Open it once in your browser; FluidCAD then remembers the browser until the container restarts, which prints a new link. The port is published on 127.0.0.1 only, so no other machine reaches it, and FLUIDCAD_ALLOWED_HOSTS=localhost makes the link name localhost rather than the container's own host name.

On a server​

Pick the example that matches your network, save it as compose.yaml next to a projects folder, and run docker compose up -d.

On a network you trust (home LAN, Tailscale), with no sign-in:

services:
fluidcad:
image: ghcr.io/fluid-cad/fluidcad:latest
ports:
- "3100:3100"
environment:
FLUIDCAD_NO_AUTH: "1"
# Every name you open FluidCAD by; any other is refused.
FLUIDCAD_ALLOWED_HOSTS: "fluidcad.example.com,192.0.2.20"
volumes:
- ./projects:/app/projects
- fluidcad-home:/home/node/.fluidcad
restart: unless-stopped

volumes:
fluidcad-home:

Open http://fluidcad.example.com:3100 from any device. Anyone who can reach that port can read and change every project, and run code on the server through them, so don't expose it beyond that network.

On a shared network (office, school), behind an HTTPS reverse proxy on the same machine (Caddy, nginx, Tailscale Serve) that forwards WebSocket upgrades:

services:
fluidcad:
image: ghcr.io/fluid-cad/fluidcad:latest
ports:
- "127.0.0.1:3100:3100"
environment:
FLUIDCAD_PUBLIC_URL: "https://fluidcad.example.com"
volumes:
- ./projects:/app/projects
- fluidcad-home:/home/node/.fluidcad
restart: unless-stopped

volumes:
fluidcad-home:

The port is published on 127.0.0.1, so only the proxy reaches it. Sign in with the link from docker compose logs fluidcad, once in each browser.

warning

FluidCAD is not built to face the internet. Keep it on a network you control, and reach it from outside through a VPN such as Tailscale.

Settings​

The container is configured through environment variables, each standing in for a flag of fluidcad:

VariableFlagDescription
FLUIDCAD_ALLOWED_HOSTS--allowed-hostComma-separated names the start screen is reached by; any other is refused
FLUIDCAD_NO_AUTH--no-auth1 drops the sign-in link; needs FLUIDCAD_ALLOWED_HOSTS
FLUIDCAD_PUBLIC_URL--public-urlThe origin a reverse proxy serves FluidCAD at, such as https://cad.example.com

Reaching FluidCAD from other machines and Without a sign-in link explain what each one protects against.

Updating​

With Compose:

docker compose pull
docker compose up -d

With docker run, pull the new image, remove the container with docker rm -f fluidcad and run it again with the same command. Your projects and the fluidcad-home volume stay as they were. To stay on one release instead of following latest, use its version as the tag: ghcr.io/fluid-cad/fluidcad:0.0.47.

To build the image yourself from a clone of the repository, replace image: with build: . in either Compose file.

Editor setup​

FluidCAD runs on its own — no editor required. Every option drives the same engine and the same live 3D viewport; pick whichever fits your workflow.

The desktop app, npx fluidcad and npx fluidcad serve all open the whole product: the 3D viewport, every interactive modelling tool, and a code editor with completion driven by the engine's own type declarations — so extrude( shows its signature and edge().onPlane( completes, always matching the version you're running.

The code editor stays hidden until you ask for it. Open it from the ☰ menu or with Ctrl+B; it takes width from the left, so the model narrows rather than being covered. Files are tabs in the top bar, added with + — there's no file tree, because the editor already knows about every file in the workspace.

Any other editor​

npx fluidcad serve works alongside any editor too: leave the browser tab on the viewport and edit .part.js in whatever you prefer — the model rebuilds on save. Opening the same file in two editors at once is the one thing to avoid.

Next​

Getting started builds a butt hinge from an empty part to an animated assembly, one tool per step.