Open-Source Animation DSL

Like Mermaid, but for motion.

Define actors, timelines, and interactions in a simple text language. The engine handles rendering. No keyframes, no drag-and-drop.

Try the Playground Learn the Syntax
npm i @markdy/core @markdy/renderer-dom
import { createPlayer } from "@markdy/renderer-dom";

createPlayer({
  container: document.getElementById("stage"),
  code: `scene width=600 height=300
  actor a = figure(#c68642, m, 😎) at (300, 150)
  @0.3: a.enter(from=left, dur=0.8)`,
  autoplay: true,
});
pnpm add @markdy/astro
---
import { Markdy } from "@markdy/astro";

const code = `
  scene width=800 height=400 bg=#fff5f9
  actor hero = figure(#c68642, m, 😎) at (400, 200)
  @0.0: hero.enter(from=left, dur=0.8)
  @1.5: hero.say("Hello!", dur=1.2)
`;
---

<Markdy {code} width={800} height={400} bg="#fff5f9" autoplay />
pnpm add @markdy/astro
import { Markdy } from "@markdy/astro";

export const code = `
  scene width=600 height=300 bg=white
  actor label = text("Hello") at (200, 130) size 40 opacity 0
  @0.3: label.fade_in(dur=0.6)
`;

<Markdy {code} width={600} height={300} autoplay />

Key Features

πŸ“¦

Zero Dependencies

Pure TypeScript parser β€” no DOM, no runtime deps.

🌐

Web-Native Renderer

Web Animations API + CSS transforms. No Canvas, no GSAP.

πŸ€–

AI-Agent Friendly

Structured DSL that LLMs can generate, validate, and iterate.

🧩

Framework Agnostic

Works anywhere. Astro island component included.

Lightweight Packages

Ship only what you need. Tiny bundles, zero bloat.

Playground

Edit the code and watch it animate. Pick an example or write your own.

Editor
Ctrl+Space autocomplete Β· Cmd+Enter run
Preview

Learn MarkdyScript

Follow this guide from basics to advanced. Each card builds on the last.

1

Scene Setup

Every animation starts by defining the canvas. This must be the first line in your .markdy file.

scene width=800 height=400 fps=30 bg=#fafafa
PropertyDefaultDescription
width800Canvas width in pixels
height400Canvas height in pixels
fps30Frame rate for the rendering engine
bgwhiteAny CSS color value (e.g. #1a1a2e)
durationautoOverride total length in seconds
2

Actors & Positioning

Actors are the objects in your scene. Place them with at (x, y) and add optional modifiers.

actor a = figure(#c68642, m, 😎) at (100, 200) scale 1.2
actor b = text("Hello World") at (50, 50) size 24
actor c = box() at (300, 200)
TypeArgumentsDescription
text"quoted string"Plain text label. Customise with size.
boxβ€”100x100 solid box. Great for prototyping.
figureskinColor, gender, faceStick figure with articulatable limbs.
spriteasset nameRenders an image or icon asset.

Modifiers: opacity (0–1), scale, rotate, size (text only), z (layer order).

3

Timeline & Motion

Schedule actions on a timeline with @time: actor.action(). Time is in decimal seconds.

@0.5: a.enter(from=left, dur=0.8)
@1.5: a.move(to=(400, 200), dur=1.0, ease=out)
@3.0: a.fade_out(dur=0.5)
ActionParametersWhat it does
enterfrom, durSlides in from canvas edge
moveto, dur, easeTranslates to target coordinates
fade_in / fade_outdurAnimates opacity
scale / rotateto, durTransforms the actor

Easing: linear, in, out, inout

4

Speech & Effects

Make actors talk with comic speech bubbles and add dynamic effects like shaking.

@1.0: a.say("Hello! πŸ‘‹", dur=1.5)
@2.5: a.shake(intensity=8, dur=0.4)
ActionParametersWhat it does
say"text", durShows an anchored speech bubble
shakeintensity, durOscillates on the X axis
throwasset, to, durLaunches a projectile between actors
5

Expressions & Limbs

figure actors have articulated limbs you can individually control for expressive animations.

@1.0: a.face("😡")
@1.5: a.rotate_part(part=arm_right, to=130, dur=0.4)
@2.0: a.punch(side=right, dur=0.2)
@2.5: a.kick(side=left, dur=0.3)
ActionParameters
face"emoji" β€” instant expression swap
rotate_partpart, to (degrees), dur
punch / kickside (left|right), dur

Body parts: head, face, body, arm_left, arm_right, leg_left, leg_right

5b

Gestures & Posing

Built-in gestures save you from chaining rotate_part calls. pose sets multiple parts at once.

@1.0: a.wave(side=right, dur=0.8)
@2.0: a.nod(dur=0.4)
@3.0: a.pose(arm_left=70, arm_right=-70, dur=0.4)
@4.0: a.jump(height=25, dur=0.5)
@4.5: a.bounce(intensity=12, count=3, dur=0.5)
ActionParametersWhat it does
waveside, durWave gesture β€” arm up, oscillate, return
noddurHead nod β€” down and up twice
posearm_left, arm_right, leg_left, leg_right, head, body, durSet multiple parts at once
jumpheight, durJump with squash/stretch
bounceintensity, count, durDiminishing vertical bounce
6

Assets & Sprites

Load external images and vector icons as assets, then render them as sprite actors.

# Declare assets first
asset cat = image("https://example.com/cat.gif")
asset fire = icon("lucide:flame")

# Render them as actors
actor meme = sprite(cat) at (400, 200) scale 0.5
actor icon = sprite(fire) at (100, 100) scale 2.0
image("url")Loads images, GIFs, photos β€” any URL or local path.
icon("set:name")Loads SVG icons from Iconify. Never blurs when scaled.
7

Variables & Templates

Avoid repetition with var for values and def for reusable actor templates.

var accent_skin = #fad4c0

def char(skin, face) {
  figure($${skin}, f, $${face})
}

actor lily = char($${accent_skin}, 😊) at (100, 200)

var substitutes values (robust for #hex colors). def creates actor factory templates β€” build character systems without any JavaScript.

8

Sequences

Package multi-step choreographies into reusable seq blocks. The ultimate power move.

seq wave(arm, angle) {
  @+0.0: $.rotate_part(part=$${arm}, to=$${angle}, dur=0.3)
  @+0.3: $.rotate_part(part=$${arm}, to=25, dur=0.3)
}

@2.0: lily.play(wave, arm=arm_left, angle=-80)

$ refers to the calling actor. Times with @+ are relative offsets from when .play() is triggered.

AI-Friendly by Design

MarkdyScript is a structured DSL that AI agents can generate, validate, and iterate on. Just describe what you want.

How it works

  1. Point your AI to the docs

    Share the AGENT.md β€” a single all-in-one reference with grammar, actions, patterns and examples.

  2. Describe your scene in plain English

    Tell the AI what you want to visualize β€” characters, actions, emotions, timing.

  3. Get valid MarkdyScript back

    The AI generates syntactically correct code. Paste it into the playground or your app.

Example prompt

You β†’ Claude / ChatGPT / Copilot
Use https://github.com/HoangYell/markdy-com/blob/main/docs/AGENT.md as a complete reference (grammar, actions, patterns, examples), then write a Markdy scene:

"A guy holding a coffee cup walks in, trips on a rock, and loses his coffee cup. The cup flies and smashes. He looks sad."

The AI reads the docs, understands the grammar, and outputs a complete .markdy scene with actors, timeline events, and expressions β€” ready to render.

Works with any AI that accepts URL context

Claude ChatGPT GitHub Copilot Cursor Windsurf

Built with Markdy

Real projects using Markdy in production.