Project Scaffolding

Create a new Cuttlefish project with the right configuration for your board and framework (the code-generation library for your target — Zephyr or native).

Create a Project

Using npx (no install required)

npx @typecad/cuttlefish create my-project --target esp32s3

Using the CLI

cuttlefish create my-project --target esp32s3

Both forms invoke the same cuttlefish create scaffolder.

Interactive Wizard

If you run cuttlefish create without a --target flag, an interactive wizard will prompt you for:

  1. Project name — defaults to the directory name
  2. Target — choose from built-in targets
  3. Framework — picked automatically from the target (Zephyr for embedded boards, native for desktop)
  4. Baud rate — serial monitor speed (default: 9600)
  5. Starter sketch — whether to generate the blink starter (default: yes)

Non-Interactive Mode

Use flags to skip the wizard:

npx @typecad/cuttlefish create my-project --target esp32-devkit --framework zephyr --baud 9600
FlagDescription
--target, -t <id>Target identifier (required for non-interactive)
--board, -b <id>Alias for --target
--framework, -f <id>Framework catalog id — native or zephyr (auto-detected from target)
--baud <rate>Serial baud rate
--no-sketchSkip generating the starter sketch
--no-installSkip the automatic npm install in the new project
--outDir, -o <path>Output directory (default: ./<name>)

After scaffolding, create automatically installs the project’s dependencies with the package manager it detects (npm, pnpm, yarn, or bun). Pass --no-install to skip this and run the install yourself.

Built-in Targets

Target IDMCUZephyr build target
esp32-devkitESP32-WROOM-32esp32_devkitc/esp32/procpu
esp32s3ESP32-S3esp32s3_devkitc/esp32s3/procpu
rp2040RP2040rpi_pico
rp2350RP2350rpi_pico2/rp2350a/m33
xiao-nrf52840nRF52840xiao_ble/nrf52840
native— (desktop executable)

For a Zephyr build, create one of the Zephyr-supported boards (esp32-devkit, esp32s3, rp2040, rp2350, or the XIAO nRF52840 via the wizard) and choose the Zephyr framework — the scaffold then writes the matching Zephyr build target (esp32_devkitc, esp32s3_devkitc, xiao_ble, rpi_pico, rpi_pico2/rp2350a/m33) and west toolchain config.

Generated Project Structure

my-project/
  package.json           # Scripts and dependencies
  tsconfig.json          # TypeScript config for Cuttlefish
  cuttlefish.config.ts   # Transpiler configuration
  .gitignore
  .cuttlefish/
    cuttlefish-env.d.ts      # Type declarations Cuttlefish adds for you
    eslint.config.mjs        # ESLint config for src/
    eslint-transpiler-rules.mjs  # Generated transpiler-compatibility rules
    board.ts                 # The generated board module (from the data pack)
  src/
    main.ts               # Starter blink sketch
  tests/
    01-basics.test.ts     # Hardware tests (run with npm run test:hw)
  sim/
    main.test.ts          # Simulator tests (run with npm run simulate)

The sim/ and tests/ tiers are generated for embedded targets; native projects get only src/main.ts.

package.json

Includes scripts for the common workflow:

  • npm run build — transpile to C++
  • npm run compile — transpile and compile
  • npm run upload — transpile, compile, and upload
  • npm run monitor — transpile, compile, upload, and open the serial monitor
  • npm run test:hw — run the hardware test tier (cuttlefish-test)
  • npm run simulate — run the simulator test tier (vitest run sim/)
  • npm run lint — ESLint over src/, including the generated transpiler-compatibility rules
  • npm run dev — watch mode (retranspile on change)
  • npm run gen-decls / npm run gen-libdefs — declaration generation helpers

Dependencies include @typecad/cuttlefish, @typecad/hal, and the framework package for the target; dev dependencies include @typecad/expect, @typecad/simulator, vitest, and the ESLint toolchain.

cuttlefish.config.ts

The main configuration file with entry point, board, framework, and output settings (as generated for an embedded target):

import type { CuttlefishConfig } from '@typecad/cuttlefish/api';

const config: CuttlefishConfig = {
  entry: './src/main.ts',
  target: 'esp32s3',
  board: 'esp32s3_devkitc/esp32s3/procpu',
  framework: '@typecad/framework-zephyr',
  frameworkData: { buildTarget: 'esp32s3_devkitc/esp32s3/procpu' },
  output: { framework: 'zephyr', outDir: './out' },
  toolchain: { type: 'west' },
  test: { port: 'COM4', baudRate: 115200, timeout: 30000, include: ['tests/**/*.test.ts'] },
};

export default config;

Zephyr projects get toolchain: { type: 'west' } and a Zephyr board target in frameworkData.

Custom Hardware (typeCAD Contract)

For custom PCBs designed in typeCAD, replace board with soc + contract:

import type { CuttlefishConfig } from '@typecad/cuttlefish/api';

const config: CuttlefishConfig = {
  entry: './src/main.ts',
  target: 'esp32s3',
  soc: 'esp32s3',
  contract: './src/my-board.contract.json',
  framework: '@typecad/framework-zephyr',
  frameworkData: { buildTarget: 'esp32s3_devkitc/esp32s3/procpu' },
  output: { framework: 'zephyr', outDir: './out' },
};

export default config;

See Contracts for the full guide on custom hardware integration.

Next Steps

Dependencies are installed by create itself, so after scaffolding:

cd my-project
npm run compile    # Build and compile
npm run upload     # Upload to board (connect via USB first)

If you used --no-install, run npm install first.