Skip to content

elmo

ELectronics MOdeling — schematics as code

GitHub · elmo.emdzej.pl

About

A text DSL for describing circuits that renders as schematics — embeddable in Markdown code fences, in the spirit of Mermaid and PlantUML.

elmo
title "555 astable"

part U1 ic "NE555" pkg=DIP-8 {
  left  2:TRIG  6:THRES  7:DISCH
  right 3:OUT   4:~RESET
  top   8:VCC
  bottom 1:GND
}
part R1 res 10k
part R2 res 47k

power VCC = U1.VCC U1.~RESET R1.1
gnd   GND = U1.GND
net n_thres = U1.THRES U1.TRIG R2.2
wire U1.OUT -> R1.1

The full language is specified in docs/language-spec.md (v0.1-final).

Features

  • Layout & routing — elkjs places components by signal flow and routes signal nets as orthogonal wires, with junction dots where wires tee. Power and ground render as symbols and are never routed.
  • ~45 iconic symbols — passives (R/C/L, ferrite, fuse, crystal, thermistor, varistor, pot, transformer), diodes (incl. zener/schottky/TVS/bridge), transistors and FETs (BJT/Darlington/IGBT/MOSFET/JFET), sources, switches, relay, antenna. ic/connector/mod are pin-labelled boxes; unknown kinds fall back to a box.
  • Orientation & placementrotate/mirror, connection-driven auto-rotation, and place/near/group hints.
  • Imports — split designs across files with namespaces; rails stay global.
  • Themingtheme dark|light|mono, else responsive to the viewer's preference.
  • Exports — netlist and BOM from the same source, using pass-through metadata.
  • Everywhere — markdown-it and remark plugins, a browser bundle, and a CLI.

Packages

PackageWhat it does
@emdzej/elmo-coreParse the DSL → IR → layout → SVG. Async render(source) entry point.
@emdzej/elmo-markdown-itmarkdown-it plugin (two-phase renderElmo) turning ```elmo fences into inline SVG
@emdzej/elmo-remarkremark/unified plugin (async) for the MDX/Docusaurus/Astro ecosystem
@emdzej/elmo-browserClient-side bundle — drop elmo.min.js on a page, Mermaid-style
@emdzej/elmo-clielmo command — render, check, and export netlist/BOM from .elmo files

Usage

ts
import { render } from "@emdzej/elmo-core";

const { svg, diagnostics } = await render(source);
ts
import MarkdownIt from "markdown-it";
import elmo, { renderElmo } from "@emdzej/elmo-markdown-it";

const md = new MarkdownIt().use(elmo);
const html = await renderElmo(md, markdownWithElmoFences);

Split a design across files with import:

elmo
import "psu.elmo" as psu
part U2 mod "ESP32-WROOM" { left 1:GND 2:3V3 }
wire psu.U1.OUT -- U2.3V3
gnd GND = psu.U1.GND U2.GND

Roadmap

Post-v1: buses/vectors and hierarchical sub-sheets.

Current version 0.3.1. Packages publish to npm on release; the docs site with live diagrams is at elmo.emdzej.pl.

Stack: TypeScript, elkjs, pnpm + Turborepo