Cached at:
06/25/26, 08:08 AM
# Markdy β Open-Source Animation DSL Engine
Source: [https://markdy.com/](https://markdy.com/)
## 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\.
Editor
Ctrl\+Space autocomplete Β· Cmd\+Enter run
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`width``800`Canvas width in pixels`height``400`Canvas height in pixels`fps``30`Frame rate for the rendering engine`bg``white`Any CSS color value \(e\.g\.`\#1a1a2e`\)`duration`*auto*Override total length in seconds
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\.`figure`skinColor, gender, faceStick figure with articulatable limbs\.`sprite`asset nameRenders an image or icon asset\.**Modifiers:**`opacity`\(0β1\),`scale`,`rotate`,`size`\(text only\),`z`\(layer order\)\.
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`enter`from, durSlides in from canvas edge`move`to, dur, easeTranslates to target coordinates`fade\_in`/`fade\_out`durAnimates opacity`scale`/`rotate`to, durTransforms the actor**Easing:**`linear`,`in`,`out`,`inout`
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`shake`intensity, durOscillates on the X axis`throw`asset, to, durLaunches a projectile between actors
`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\_part`part, to \(degrees\), dur`punch`/`kick`side \(left\|right\), dur**Body parts:**`head`,`face`,`body`,`arm\_left`,`arm\_right`,`leg\_left`,`leg\_right`
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`wave`side, durWave gesture β arm up, oscillate, return`nod`durHead nod β down and up twice`pose`arm\_left, arm\_right, leg\_left, leg\_right, head, body, durSet multiple parts at once`jump`height, durJump with squash/stretch`bounce`intensity, count, durDiminishing vertical bounce
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\.
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\.
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\.
### How it works
1. **Point your AI to the docs**Share the[AGENT\.md](https://github.com/HoangYell/markdy-com/blob/main/docs/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
> 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\.