Skip to content

About

A server that takes encoded tscircuit code and renders it into an SVG suitable for use in docs

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Repository files navigation

svg.tscircuit.com

A server that takes encoded tscircuit code or circuit JSON and renders it into SVG or PNG assets suitable for use in docs.

Example Output URLs

View Preview
PCB Layout (SVG) Example PCB layout generated by svg.tscircuit.com
Schematic (SVG) Example schematic generated by svg.tscircuit.com
Schematic Simulation (SVG) Example schematic simulation generated by svg.tscircuit.com
Assembly (SVG) Example assembly view generated by svg.tscircuit.com
Pinout (SVG) Example pinout generated by svg.tscircuit.com
3D Render (PNG) Example 3D render generated by svg.tscircuit.com

API Overview

This service converts TSCircuit code or pre-generated circuit JSON into various visual formats (PCB, schematic, assembly, pinout, and 3D views) via HTTP requests. It's designed to be used for generating circuit diagrams, assembly documentation, pinout diagrams, PCB layouts, and 3D visualizations for documentation and web applications.

API Endpoints

1. SVG Generation (Main Endpoint)

URL: GET /?svg_type={type}&code={encoded_code} or POST /?svg_type={type} with circuit_json in body

Parameters:

  • svg_type (required for SVG/PNG images): The type of SVG to generate
    • pcb - PCB layout view
    • schematic - Circuit schematic view
    • schsim - Schematic simulation view with graph regions
    • sim - Simulation graph view
    • assembly - Assembly overlay view with components and labels
    • pinout - Pinout diagram view
    • 3d - 3D visualization view
  • format (optional): Output format. Defaults to svg. Set format=png to receive a PNG rasterized version. PNG-specific query parameters:
    • png_width / png_height
    • png_density
  • show_infinite_grid (optional): For 3D views only. Set to true to display an infinite grid in the 3D render. Default: false
  • camera_preset (optional): For 3D PNG/SVG images, choose a named view from circuit-json-to-3d-png (such as top-down, top-left-corner, top-right-corner, front, or top-center-angled). Also supports bottom / bottom-up for the underside and bottom-center-angled for an angled underside view. Accepts a URL parameter or POST JSON field; POST overrides the URL. Unknown presets return HTTP 400. Omission retains the default camera.
  • format=glb (optional): Download the 3D model without requiring svg_type or view as model/gltf-binary. Uses the same code, file map, or Circuit JSON inputs as images. The response has Content-Disposition: attachment; filename="circuit.glb" and allows cross-origin model viewers. Camera and lighting do not change the downloaded model. The Vercel and svg3 adapters both preserve binary GLB bytes.
  • realistic (optional): For 3D views only, in both PNG and SVG output. Set to true for studio lighting, soft shadows, and reflections. Default: false. Accepts boolean values in POST JSON or true/false, 1/0, yes/no, and on/off in the URL. A POST body value overrides the URL value. Realistic rendering takes longer than regular rendering; use PNG output to retain the shading detail.
  • show_debug_objects (optional): For PCB views only. Set to true to render pcb_debug_object overlays such as autorouting phase bounds. Default: false
  • viewbox (optional): For PCB views, a real-coordinate crop formatted as minX,minY,maxX,maxY. Elements crossing the region remain rendered but are clipped to this view.
  • simulation_experiment_id (optional): For sim and schsim, render the experiment with this Circuit JSON id.
  • simulation_experiment_name (optional): For sim and schsim, render the uniquely named experiment. If neither selector is provided, the first experiment is rendered.

Input Methods:

  • code (GET/POST query parameter): Base64-encoded and compressed TSCircuit code
  • circuit_json (GET query parameter or POST body): For GET, pass base64-encoded Circuit JSON (optionally gzip-compressed). For POST, pass raw Circuit JSON as {"circuit_json": {...}}.
  • fs_map (GET query parameter or POST body): Map of filenames to file contents. For GET requests, provide the map as a gzip-compressed, base64-encoded JSON string (e.g. using encodeFsMapToHash from lib/fsMap) or as a JSON stringified object. For POST requests, send { "fs_map": { "index.tsx": "export default () => ..." } }. Optionally include an entrypoint value to specify which file should be executed (defaults to index.tsx).

Either code, fs_map, or circuit_json must be provided.

Response: SVG content with image/svg+xml content type (default) or PNG content with image/png when format=png

Example Request with Code:

curl "https://svg.tscircuit.com/?svg_type=pcb&code=eyJjb2RlIjoiZXhwb3J0IGRlZmF1bHQgKCkgPT4gKFxuICA8Ym9hcmQgd2lkdGg9IjEwbW0iIGhlaWdodD0iMTBtbSI+XG4gICAgPHJlc2lzdG9yXG4gICAgICByZXNpc3RhbmNlPSIxayJcbiAgICAgIGZvb3RwcmludD0iMDQwMiJcbiAgICAgIG5hbWU9IlIxIlxuICAgICAgc2NoWD17M31cbiAgICAgIHBjYlg9ezN9XG4gICAgLz5cbiAgICA8Y2FwYWNpdG9yXG4gICAgICBjYXBhY2l0YW5jZT0iMTAwMHBGIiBcbiAgICAgIGZvb3RwcmludD0iMDQwMiJcbiAgICAgIG5hbWU9IkMxIlxuICAgICAgc2NoWD17LTN9XG4gICAgICBwY2JYPSstM31cbiAgICAvPlxuICAgIDx0cmFjZSBmcm9tPSIuUjEgPiAucGluMSIgdG89Ii5DNSA+IC5waW4xIiAvPlxuICA8L2JvYXJkPlxuKSJ9"

Example Request with Circuit JSON:

curl "https://svg.tscircuit.com/?svg_type=pcb&circuit_json=BASE64_ENCODED_JSON"

Example Request with fs_map (GET):

curl "https://svg.tscircuit.com/?svg_type=pcb&fs_map=ENCODED_FS_MAP"

Example Request with fs_map (POST):

curl "https://svg.tscircuit.com/?svg_type=pcb" \
  -H "Content-Type: application/json" \
  -d '{
    "fs_map": {
      "index.tsx": "export default () => <board>...</board>"
    },
    "entrypoint": "index.tsx"
  }'

Example Request with a custom tscircuit.config.ts (TI parts engine):

curl "https://svg.tscircuit.com/?svg_type=pcb" \
  -H "Content-Type: application/json" \
  -d '{
    "fs_map": {
      "package.json": "{\"dependencies\":{\"@tscircuit/ti-parts-engine\":\"github:tscircuit/ti-parts-engine\"}}",
      "tscircuit.config.ts": "import { createTiPlatformConfig } from \"@tscircuit/ti-parts-engine\";\nexport default { platformConfig: createTiPlatformConfig() };",
      "index.circuit.tsx": "export default () => (<board><chip footprint=\"ti:LM358\" name=\"U1\" /></board>);"
    },
    "main_component_path": "index.circuit.tsx"
  }'

2. Health Check

URL: GET /health

Response: JSON with status

{"ok": true}

3. URL Generation Page

URL: GET /generate_url?code={encoded_code}

Response: HTML page for generating shareable URLs

4. Index Page

URL: GET /

Response: HTML page with usage instructions

Usage Examples

TSCircuit Code

export default () => (
  <board width="10mm" height="10mm">
    <resistor
      resistance="1k"
      footprint="0402"
      name="R1"
      schX={3}
      pcbX={3}
    />
    <capacitor
      capacitance="1000pF"
      footprint="0402"
      name="C1"
      schX={-3}
      pcbX={-3}
    />
    <trace from=".R1 > .pin1" to=".C1 > .pin1" />
  </board>
)

API Calls

PCB Layout:

curl "https://svg.tscircuit.com/?svg_type=pcb&code=YOUR_ENCODED_CODE"

PNG Output:

curl "https://svg.tscircuit.com/?svg_type=pcb&format=png&code=YOUR_ENCODED_CODE"

Schematic View:

curl "https://svg.tscircuit.com/?svg_type=schematic&code=YOUR_ENCODED_CODE"

Named Simulation Graph:

curl "https://svg.tscircuit.com/?svg_type=sim&simulation_experiment_name=Root%20Fast&code=YOUR_ENCODED_CODE"

Named Schematic Simulation:

curl "https://svg.tscircuit.com/?svg_type=schsim&simulation_experiment_name=Input%20Group&code=YOUR_ENCODED_CODE"

Each simulation request returns one static SVG. Use a unique name on every <analogsimulation />, then create one URL per name when presenting multiple simulation results. Use simulation_experiment_id when names are duplicated.

Assembly View:

curl "https://svg.tscircuit.com/?svg_type=assembly&code=YOUR_ENCODED_CODE"

Pinout View:

curl "https://svg.tscircuit.com/?svg_type=pinout&code=YOUR_ENCODED_CODE"

3D Visualization:

curl "https://svg.tscircuit.com/?svg_type=3d&code=YOUR_ENCODED_CODE"

Realistic 3D PNG:

curl "https://svg.tscircuit.com/?svg_type=3d&format=png&realistic=true&code=YOUR_ENCODED_CODE" \
  -o realistic.png

Bottom preview and rotatable model:

curl "https://svg.tscircuit.com/?svg_type=3d&format=png&camera_preset=bottom-center-angled&code=YOUR_ENCODED_CODE" -o bottom.png
curl "https://svg.tscircuit.com/?format=glb&code=YOUR_ENCODED_CODE" -o circuit.glb

At svg3.tscircuit.com, a 3D image render also saves the GLB produced during conversion in KV. A subsequent GLB download reuses those exact bytes without evaluating or converting the circuit again. See svg3 caching.

For 3D SVG output, use format=svg with the same realistic=true flag. To render Circuit JSON from a file, POST {"circuit_json": [...], "realistic": true}:

curl "https://svg.tscircuit.com/?svg_type=3d&format=png" \
  -H "Content-Type: application/json" \
  --data-binary @request.json \
  -o realistic.png

Code Encoding

The code parameter must be a compressed and base64-encoded string. You can use the @tscircuit/create-snippet-url package to generate these:

import { getCompressedBase64SnippetString } from "@tscircuit/create-snippet-url"

const tscircuitCode = `
export default () => (
  <board width="10mm" height="10mm">
    <led name="LED1" />
  </board>
)
`

const encodedCode = getCompressedBase64SnippetString(tscircuitCode)
const apiUrl = `https://svg.tscircuit.com/?svg_type=pcb&code=${encodeURIComponent(encodedCode)}`

To use circuit_json, base64 encode the circuit JSON:

const circuitJson = { /* ... */ }
const encodedJson = Buffer.from(JSON.stringify(circuitJson)).toString("base64")
const apiUrl = `https://svg.tscircuit.com/?svg_type=pcb&circuit_json=${encodeURIComponent(encodedJson)}`

Response Headers

Successful responses include:

  • Content-Type: image/svg+xml (SVG) or image/png (PNG)
  • Cache-Control: public, max-age=300, stale-while-revalidate=604800, stale-if-error=604800
  • CDN-Cache-Control: public, s-maxage=43200, stale-while-revalidate=604800, stale-if-error=604800

Error Handling

When errors occur, the API returns an image with error information instead of the requested circuit asset. Error responses use HTTP 500 and include:

  • Content-Type: image/svg+xml (or image/png when format=png)
  • Cache-Control: no-store
  • CDN-Cache-Control: no-store

Caching

Generated images stay fresh in the CDN for 12 hours. After that, the CDN serves the previous image immediately while rendering an updated version in the background, for up to seven days. If rendering fails, the previous successful image can still be served during that window. Error images are never cached. Browsers cache images for five minutes before revalidating.

To refresh a stale image synchronously (for example, in a daily cache warmer), GET its original URL with Pragma: no-cache and Cache-Control: no-cache request headers. Keep the URL unchanged: adding a cache-busting query parameter creates a different cache entry. Vercel returns x-vercel-cache: REVALIDATED when a stale entry has been refreshed. A fresh entry can return HIT.

These headers apply to GET image URLs. POST requests are rendered on demand. CDN caching is regional and entries can be evicted; the first request for a missing entry still waits for rendering.

Development

bun run start

Deployment targets

The shared renderer is used by the Vercel adapter in svg2 and the Cloudflare Worker, KV cache, and Containers service in svg3. The existing Vercel build commands and public domain remain unchanged.

About

A server that takes encoded tscircuit code and renders it into an SVG suitable for use in docs

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages