TypeScript in / inspectable Wasm out

Pulse

Portable without pretending every host is the same.

Write routing, middleware, schemas, state, config, and capabilities through one explicit context. Pulse shows exactly what lowers to provider-neutral Native Wasm and refuses hidden fallback.

What the Beta supports →
Pulse 1.0.0-beta.1 — BetaExplicit Native and JavaScript targetsActivation: documentation-release

Start with the application

One Router. One explicit ctx surface. No host SDKs in your handlers.

Request metadata, headers, route parameters, state, responses, and bounded effects all live on ctx. Native builds turn trusted awaits into explicit effects and continuations without adding a Promise runtime.

Explore the context API
app.tsRouter example
import { Router } from '@pulse-compute/runtime'

const app = new Router()

app.use(async (ctx, next) => {
  if (!ctx.req.header('authorization')) {
    return ctx.json({ error: 'unauthorized' }, { status: 401 })
  }

  return next()
})

app.get('/users/:id', async (ctx) => {
  const id = ctx.param('id')
  const user = await ctx.fetch('https://users.example.test/users/' + id).json()

  return ctx.json({ id, user })
})

export default app

Context is the boundary

Read headers and route parameters, carry invocation state, and construct responses through one documented API.

Consequential work stays visible

Network, storage, config, secrets, and outbound events are explicit effects that inspect can report.

Targets never change silently

Unsupported Native source fails at the exact boundary; Pulse does not switch the application to JavaScript.

Try it locally

Get a project running without learning the compiler first.

The CLI keeps setup, checks, local development, and builds in one place. The deeper compiler view is there when it becomes useful.

quick start
$ npm install --global @pulse-compute/cli@1.0.0-beta.1
$ pulse init ./my-app
$ cd ./my-app
$ npm install
$ pulse dev

A gradual path

Start with readable TypeScript. Tighten only what you choose.

Pulse gives routing, schemas, host capabilities, and target selection separate homes. You can adopt the contract first, inspect the boundary, and move eligible paths to Native without rewriting the service shape.

Understand the architecture
Structure the applicationRouter, terminal middleware, config, assets, and capabilities follow one set of patterns.
See the boundaryInspect effects, schemas, and unsupported source before deployment.
Choose deliberatelyBuild the target you configured; Pulse never changes it behind your back.
Refine over timeReplace opaque dependencies with trusted effects and regain native eligibility.

Less friction later

Keep deployment decisions out of application code.

Profiles and capability packages contain environment-specific mechanics. Route and event code consume the stable contract, so changing a host realization does not require branching through the application.

Read the contract model
01

One application shape

Routing, middleware, responses, assets, and capabilities use consistent patterns.

02

Explicit host work

Config, secrets, storage, and network access are visible instead of ambient.

03

Contained environment logic

Profiles select realizations; application code consumes capabilities rather than branching on deployment.

04

Honest failure

When a target cannot lower something, Pulse points to the exact boundary instead of quietly changing execution.

Under the hood

See the exact program Pulse will build.

pulse inspect reports routes, schemas, capabilities, effects, continuations, target eligibility, and the selected plan before deployment. The evidence is optional during ordinary work and precise when a boundary matters.

Open the CLI reference
pulse inspect --jsonShow compiler details
3Capabilities
7Effects
3Continuations
{
  "provider": "node",
  "capabilities": [
    "fetch",
    "response.json",
    "response.text"
  ],
  "effects": [
    {
      "id": "fetch-1",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-2",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-3",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-4",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-5",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-6",
      "kind": "fetch",
      "operation": "dispatch"
    },
    {
      "id": "fetch-7",
      "kind": "fetch",
      "operation": "dispatch"
    }
  ],
  "continuations": [
    {
      "id": "continuation-1",
      "kind": "single-fetch",
      "effectIds": [
        "fetch-1"
      ]
    },
    {
      "id": "continuation-2",
      "kind": "fetch-group",
      "effectIds": [
        "fetch-2",
        "fetch-3",
        "fetch-4"
      ]
    },
    {
      "id": "continuation-3",
      "kind": "parallel-group",
      "effectIds": [
        "fetch-5",
        "fetch-6",
        "fetch-7"
      ]
    }
  ],
  "providerLowering": {
    "provider": "node",
    "requirements": [
      "fetch",
      "response.json",
      "response.text"
    ],
    "operations": [
      {
        "id": "fetch-1",
        "lowering": "node.fetch.dispatch",
        "binding": "https://users.example.test"
      },
      {
        "id": "fetch-2",
        "lowering": "node.fetch.dispatch",
        "binding": "https://users.example.test"
      },
      {
        "id": "fetch-3",
        "lowering": "node.fetch.dispatch",
        "binding": "https://stats.example.test"
      },
      {
        "id": "fetch-4",
        "lowering": "node.fetch.dispatch",
        "binding": "https://flags.example.test"
      },
      {
        "id": "fetch-5",
        "lowering": "node.fetch.dispatch",
        "binding": "https://users.example.test"
      },
      {
        "id": "fetch-6",
        "lowering": "node.fetch.dispatch",
        "binding": "https://stats.example.test"
      },
      {
        "id": "fetch-7",
        "lowering": "node.fetch.dispatch",
        "binding": "https://flags.example.test"
      }
    ]
  }
}

Beta

Four proven execution modes. One conformance contract.

Node and Fastly each execute explicit Native and JavaScript targets through one four-mode conformance corpus. ESP32 and browser event conformity remain clearly labeled forward host work.

See current and forward targets

Supported

  • Router, terminal middleware, schemas, and core capabilities
  • Compact provider-neutral Native Wasm and deployable Fastly Wasm
  • Explicit Node and Fastly JavaScript execution and packaging
  • Synchronous thresholded logging with host-owned output
  • Local development, offline candidates, and verified native-host execution
  • Stable diagnostics, versioned documentation, and release tooling

Outside the Beta contract

  • Automatic fallback or hidden target changes
  • General Promise semantics in native builds
  • Arbitrary host SDK access inside application code
  • Third-party lowerers or hosts without an explicit contract