This guide walks through setting up Aesthetic Function from a fresh clone to your first reconciliation run.
- Node.js 18+ — nodejs.org
- pnpm —
npm install -g pnpm - Figma desktop app — required for the plugin (optional for CLI-only usage)
git clone <repo-url>
cd aesthetic-function
pnpm installThis installs all five packages: shared, watcher, server, figma-plugin, and cli.
Generate a project config file:
af initThis creates af.config.json with defaults. You can also specify a policy profile:
af init --profile balancedAvailable profiles:
| Profile | Behavior |
|---|---|
designer-first |
Preserves design overrides aggressively (default) |
code-first |
Code wins on all conflicts |
balanced |
Equal weight to code and design signals |
strict-review |
Requires explicit approval for drift |
If you skip this step, AF uses built-in defaults.
You need two processes running: the server (message relay) and the watcher (reconciliation engine).
af run# Terminal 1: relay server on port 3001
pnpm dev:server
# Terminal 2: file watcher
pnpm dev:watcherThe Figma plugin cannot reach localhost directly. You need a tunnel.
# Terminal 3
pnpm tunnelThis runs cloudflared and prints a public URL (e.g., https://random-words.trycloudflare.com). Copy this URL.
Alternative: use ngrok (ngrok http 3001).
- In Figma, go to Plugins → Development → Import plugin from manifest...
- Select:
packages/figma-plugin/manifest.json - Run the plugin: Plugins → Development → Aesthetic Function
- In the plugin UI, paste the tunnel URL (not
localhost) - Click Connect
- You should see "Connected (WebSocket)" or "Connected (Polling)"
AF analyzes React component files that contain @figma comment markers. The demo-app/ directory has examples:
// demo-app/src/App.tsx
function App() {
return (
// @figma layout:column gap:16 padding:24
<div className="app-container">
{/* @figma font:heading color:#1a1a1a */}
<h1>Welcome</h1>
</div>
);
}Markers follow the pattern @figma property:value. These tell AF what the code intends the design to look like.
Reconcile a single file:
af reconcile demo-app/src/App.tsxThis runs the full analysis pipeline:
- Parse — Extract
@figmamarkers and AST structure - Resolve — Apply precedence rules (
override > marker > ast > code) - Diff — Compare resolved values against current design state
- Report — Output drift summary with field-level detail
af status demo-app/src/App.tsxaf dashboard demo-app/src/App.tsxaf dashboard --project demo-app/src/Every reconciliation produces artifacts in design-materializations/. Inspect them:
# List all artifacts for a file
af artifacts list demo-app/src/App.tsx
# Inspect a specific artifact
af artifacts inspect design-materializations/demo-app__src__App.figma-reconcile.json
# Trace the full pipeline for a file
af artifacts trace demo-app/src/App.tsxIf you have a Figma access token, you can pull design data:
export FIGMA_ACCESS_TOKEN=your-token-here
export FIGMA_FILE_KEY=your-file-key
# Pull tokens, components, and styles
af design pull
# Pull and normalize design tokens
af design tokens
# Inspect a specific component
af design inspect ButtonPrimaryRun the CI gate summary on a directory:
af ci demo-app/src/In strict mode (for CI pipelines):
af ci demo-app/src/ --strict --fail-on-worseningThis exits with code 1 if drift exceeds thresholds, suitable for GitHub Actions or other CI systems.
| Variable | Default | Description |
|---|---|---|
FIGMA_ACCESS_TOKEN |
— | Figma Personal Access Token |
FIGMA_FILE_KEY |
— | Figma file key |
USE_LLM_ANALYZER |
false |
Enable LLM intent parsing (optional, with fallback) |
TRACE |
false |
Enable trace logging |
PORT |
3001 |
Server port |
SERVER_URL |
http://localhost:3001 |
Server URL for watcher |
For the complete environment variable reference, see architecture-reference.md.
- CLI Reference — All commands, flags, and examples
- Architecture Reference — Runtime boundaries, reconciliation model, invariants
- README — Product overview