Vintage Machine Works

Quickstart

Write and run your first machine in minutes.

Install the CLI

Download the vintage binary for your platform from the releases page and add it to your PATH.

# Verify the installation
vintage --version

The CLI is a self-contained binary — no Node.js or Bun installation required.


Install the core package

Your machine code depends on @vintage/core for the BaseMachine base class:

bun add @vintage/core

Write your first machine

Create a file called counter.ts:

import { BaseMachine } from "@vintage/core"

interface CounterState {
	count: number
}

class CounterMachine extends BaseMachine<CounterState> {
	__NAME = "counter"
	protected initialState: CounterState = { count: 0 }

	actions = {
		increment: this.createNoArgAction(() => {
			this.updateState({ count: this.state.count + 1 })
		}, "Increment the counter"),

		decrement: this.createNoArgAction(() => {
			this.updateState({ count: this.state.count - 1 })
		}, "Decrement the counter"),
	}
}

export default CounterMachine

A few things to note:

  • __NAME becomes the machine's ID (e.g. counter)
  • initialState defines the shape and default values of state
  • Actions are defined in the actions object using createNoArgAction or createAction
  • updateState() merges a partial update and broadcasts the new state to all connected clients

Start the server

vintage serve counter.ts

The server starts on port 4000 by default. You'll see output like:

✓ counter  →  http://localhost:4000

What you get

EndpointDescription
GET /api/counter/stateCurrent machine state as JSON
POST /api/counter/actions/:nameInvoke an action
GET /api/wsWebSocket for real-time state updates
GET /Auto-generated web UI

Open http://localhost:4000 in your browser to interact with the machine through the generated UI.


Next steps

On this page