Native

The Native framework turns your TypeScript into standard C++ that links against the C/C++ standard library and compiles to a desktop executable. There is no hardware in the loop. Use this framework to test HAL logic on your laptop, run simulations, or build terminal apps without needing a microcontroller.

Prerequisites

  1. Install a C++ compiler — g++ or clang++.

    • Linux: install g++ through your package manager (apt install g++, dnf install gcc-c++, etc.).
    • macOS: install Xcode Command Line Tools (xcode-select --install), which provides clang++.
    • Windows: install MSYS2, then add C:\msys64\ucrt64\bin to your PATH so g++ is visible.
  2. Confirm the install. Watch for a version string:

    g++ --version

Quick start

Scaffold a project and target generic:

npx @typecad/cuttlefish create my-project --target native
cd my-project

Dependencies are installed by create automatically.

The generated cuttlefish.config.ts sets framework: '@typecad/framework-native'. Build and run:

npx @typecad/cuttlefish build --compile
./main            # Linux / macOS
main.exe          # Windows

What it does

Cuttlefish turns your TypeScript into C++ with a standard int main(), std::string for strings, and std::thread for async work. Numeric types map to standard C++: TypeScript’s number becomes long long, and float becomes double.

The framework includes runtime polyfills for the JavaScript methods your code relies on — string methods, array methods, math, JSON helpers — so TypeScript that runs on hardware also runs on the desktop.

A native: block in cuttlefish.config.ts exposes compiler options:

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

const config: CuttlefishConfig = {
  entry: './src/main.ts',
  target: 'generic',
  framework: '@typecad/framework-native',
  native: {
    compiler: 'g++',          // or 'clang++'; auto-detected if omitted
    cxxStandard: 'c++17',     // default
    includePaths: ['./include'],   // -I
    libraryPaths: ['/usr/local/lib'], // -L
    libraries: ['pthread'],   // -l
    warnings: 'basic',        // 'none' | 'basic' | 'all' | 'extra' | 'error'
    staticLink: true,         // default true on Windows, false elsewhere
  },
};

export default config;

For graphics, the framework supports an SDL display driver for terminal and GUI preview work.

⚙️ Advanced details — what doesn't work on Native

Native targets a desktop executable, not a microcontroller. The hardware-facing APIs that don’t have a desktop equivalent are stubbed:

  • GPIO watchers (ui.watchPin, ui.press) have no native equivalent and emit a transpile-time diagnostic.
  • Digital read is a no-op returning LOW. Pin watchers never fire.

This is a testing and simulation target. Anything that depends on real hardware behavior needs to be tested on hardware with one of the embedded frameworks.

On Native, the HAL timing API uses the C++ standard library: Time.sleep becomes std::this_thread::sleep_for and the clocks read std::chrono::steady_clock. setInterval/setTimeout run from a std::thread-backed timer pool — Native is a host target, and the JS-named timers exist only there; embedded targets use Thread. await Async.sleep(ms) becomes a non-blocking wait.

What’s different

Pick Native when there’s no hardware in the loop. For actual microcontroller firmware, use Zephyr — a real RTOS with devicetree-driven pin resolution.