Development

Development

How it has been built

The project is young — its visible history is a handful of commits over a few days in September 2026 — and it has been built with AI coding agents as a deliberate part of the workflow. AGENTS.md and CLAUDE.md carry the repository's standing instructions, and docs/ holds implementation plans that are updated as phases land rather than written once and abandoned.

The habit that does the most work is the validation loop. Each substantial change is expected to pass:

node --experimental-strip-types --test tests/*.test.mjs
pnpm exec tsc --noEmit
pnpm exec eslint .
pnpm build
Before a change lands
  1. 1

    Unit testsnode --test tests/*.test.mjs

    Property normalisation, Parquet and SGEO decoding, camera sync, loading progress and project lists.

  2. 2

    Type checktsc --noEmit

    Modules drifting from each other and from the shapes Speckle's APIs return.

  3. 3

    Linteslint .

    React and Next.js rule violations.

  4. 4

    Production buildpnpm build

    Failures that only appear in the webpack build that ships.

  5. Live validation

    Whether the format was really understood: a real project, model and version, recorded in docs/ with what was observed.

The first four gates are commands. The last is the one that turns a passing suite into evidence.

Tests run on Node's built-in test runner with type stripping, so they import the TypeScript modules directly with no build step or test framework. They cover the parts where being quietly wrong is most expensive: property normalisation, the Parquet and SGEO decoders, camera synchronisation, viewer loading progress, and project list handling.

Alongside that, the docs record live validation against real models, naming the project, model and version used, and what was actually observed. A green test suite says the decoder does what its author expected; only real geometry says the format was understood correctly.

Running it locally

Clone signs in through an OAuth application registered on a Speckle server, so it needs that application's credentials before it can do anything.

Copy .env.example to .env.local and fill in SPECKLE_APP_ID and SPECKLE_APP_SECRET from an application you have registered on your Speckle server. Set NEXT_PUBLIC_BASE_URL to http://localhost:3000 and register http://localhost:3000/api/speckle-connect as the application's redirect URL.

From Speckle application to .env.local
  • Application IDSPECKLE_APP_ID
  • Application secretSPECKLE_APP_SECRET

    Secret: it stays in .env.local and out of version control.

  • Redirect URL http://localhost:3000/api/speckle-connectNEXT_PUBLIC_BASE_URL=http://localhost:3000

    Both sides must name the same origin.

  • Server the application lives onSERVER_URL

    Optional. Defaults to https://app.speckle.systems.

Restart pnpm dev after changing any of these values.

Then:

pnpm install
pnpm dev

Restart the dev server after changing environment variables. Keep .env.local out of version control. If you develop against a self-hosted server rather than app.speckle.systems, read Server addresses first: one endpoint is still hard-coded.