Skip to content

Development setup

github-actions[bot] edited this page Sep 25, 2026 · 1 revision

Development

How to run Thingport locally with hot reload, so you can work on it. If you just want to run an instance, follow the Docker Compose instructions in the README instead.

What's in the repo

Directory What it is
backend/ Express + Prisma API (TypeScript). Serves everything under /api/*.
frontend/ React + Vite single-page app.
extension/ "Thingport Grab" browser extension -- plain unbundled JS, no build step.
bridge/ Slicer bridge helper app (Go).
docs/ This documentation.

Prerequisites

  • Node.js 20 or newer. backend/package.json sets engines.node >= 20, and CI builds on 20.
  • Docker, to run Postgres. Everything else runs natively so you get hot reload.
  • Go 1.21+ -- only if you're changing bridge/.

1. Install dependencies

git clone https://github.com/TautvydasDerzinskas/Thingport.git
cd Thingport

npm install              # root -- installs the husky pre-commit hook
npm --prefix backend ci
npm --prefix frontend ci

Each project has its own package-lock.json; there is no workspace root tying them together.

2. Start Postgres

The db service in docker-compose.yml has no host port mapping on purpose -- it's only reachable from inside the Compose network, so a natively-run backend cannot connect to it. Run your own container for development:

docker run -d --name thingport-db \
  -e POSTGRES_USER=thingport \
  -e POSTGRES_PASSWORD=thingport \
  -e POSTGRES_DB=thingport_dev \
  -p 5432:5432 \
  postgres:16-alpine

If something already listens on 5432, map a different host port and adjust DATABASE_URL below.

3. Configure the backend

cp backend/.env.example backend/.env

backend/.env.example is written for the Docker Compose deployment, so two values must change for local development:

Variable Set it to Why
DATABASE_URL postgresql://thingport:thingport@localhost:5432/thingport_dev?schema=public The example points at db:5432 -- the Compose service hostname, which doesn't resolve outside Docker.
FILE_STORAGE an absolute or relative path you own, e.g. ./storage The example uses /app/storage, the path inside the container.

Also set AUTH_SECRET to any non-empty random string -- it signs login tokens, and the example value is a placeholder.

Leave API_PORT=8000. The Vite dev server proxies /api to http://localhost:8000 (frontend/vite.config.js), so changing one means changing both.

backend/.env is gitignored. Never commit it.

4. Create the database schema

cd backend
npm run prisma:generate    # required -- there is no postinstall hook, so the client isn't generated by `npm ci`
npx prisma migrate deploy  # applies the 27 committed migrations

5. Run it

In two terminals:

npm --prefix backend run dev     # tsx watch  -> http://localhost:8000
npm --prefix frontend run dev    # vite --host -> http://localhost:5173

Open http://localhost:5173. The first account you register becomes the admin -- see backend/src/routes/auth.ts, which bootstraps the first user as ADMIN and everyone after as MEMBER.

Optional: FlareSolverr

Thingiverse sits behind Cloudflare, and some imports need FlareSolverr to get through. It's optional -- leave FLARESOLVERR_URL blank to disable it and those imports will simply fail.

docker run -d --name thingport-flaresolverr -p 8191:8191 ghcr.io/flaresolverr/flaresolverr:latest

Then set FLARESOLVERR_URL=http://localhost:8191/v1 in backend/.env.

Running the tests

Backend

19 test files, 151 tests. They run against a real Postgres database, registering accounts and creating and deleting rows as they go.

Warning

npm test loads DATABASE_URL from backend/.env through dotenv. If that points at your development database, the suite will mutate it. Always pass the variable on the command line -- an explicit shell variable takes precedence over .env, so this is safe.

docker run -d --name thingport-test-db \
  -e POSTGRES_USER=thingport -e POSTGRES_PASSWORD=thingport -e POSTGRES_DB=thingport_test \
  -p 55432:5432 postgres:16-alpine

cd backend
export TEST_DB="postgresql://thingport:thingport@localhost:55432/thingport_test?schema=public"

DATABASE_URL="$TEST_DB" npx prisma migrate deploy
DATABASE_URL="$TEST_DB" FILE_STORAGE=/tmp/thingport-test-storage npm test

The suite takes about 30 seconds. It runs test files sequentially on purpose -- several files mutate the same global Setting rows, and parallel workers race each other. See the comment in backend/vitest.config.ts.

Frontend

There are no frontend tests yet. npm run test:run uses --passWithNoTests, so it succeeds against an empty suite. New tests are welcome.

Quality checks

Command What it runs
npm --prefix backend run lint oxlint
npm --prefix frontend run lint oxlint
npm --prefix frontend run typecheck tsc --noEmit
npm --prefix frontend run verify typecheck + lint + tests + build

A husky pre-commit hook runs oxlint over whichever project you touched (see lint-staged.config.js). It does not typecheck, so run typecheck yourself before pushing frontend changes -- CI will.

Extension

extension/ has no build step; the directory is loaded as-is.

  • Chrome: chrome://extensions -> enable Developer mode -> Load unpacked -> select extension/.
  • Firefox: about:debugging#/runtime/this-firefox -> Load Temporary Add-on -> select extension/manifest.json.

Point it at http://localhost:5173 in the popup. Note that Chrome runs background.js as a service worker while Firefox runs it as a background page -- if you add top-level code there, make sure it works in both. See extension/README.md.

Bridge

cd bridge
go test ./...
go run ./cmd/thingport-bridge

macOS URL-scheme handling uses Cocoa and needs cgo, so the macOS build only works on a Mac. Windows and Linux binaries cross-compile with CGO_ENABLED=0.

Related documents

Clone this wiki locally