DEV Community

Cover image for Type-Safe SVGs with Mirrow: A New DSL for Modern Frontend Graphics
Osa George-Mannella
Osa George-Mannella

Posted on

Type-Safe SVGs with Mirrow: A New DSL for Modern Frontend Graphics

TL;DR: Mirrow is a DSL for SVGs that introduces compile-time type safety, structural validation, and a more intuitive attribute model. In this post I’ll show how it works, compare it to “raw” SVG, and guide you through setup and examples.

Vector graphics have become the backbone of modern web development, with SVGs emerging as the universal standard for scalable graphics. Yet while SVGs dominate web vector graphics, the tooling ecosystem has remained largely stagnant since the XML era. We believe it's time to strip away the tedious nature of SVG authoring to make this wonderful technology more accessible.

My Journey to Building Mirrow

I started developing Mirrow after growing increasingly frustrated with the current vector graphics landscape. We have a plethora of JavaScript libraries like GSAP and Snap.svg which excel at manipulating SVGs at runtime, and they serve their purposes well.

This is great; however, these tools never addressed my fundamental pain points with SVG authoring itself. I wanted to shift left: instead of mutating SVGs at runtime, I wanted to verify them at compile time. The goal was to enforce structure and protocol on XML that has historically been overly dynamic and error-prone.

Compile-Time Safety: Mirrow's Core Innovation

Mirrow enforces structure through three key mechanisms: attribute typing, required attributes, and permitted children validation, all at compile time.

Silent Failures in XML

Consider this invalid SVG structure:

<circle cx="50" cy="50" r="30" fill="red">
  <rect x="10" y="10" width="20" height="20"/> 
</circle>
Enter fullscreen mode Exit fullscreen mode

This SVG is completely invalid because both circle and rect are leaf nodes that cannot act as parent elements. Yet traditional XML parsing provides no feedback about this structural error. The broken SVG renders silently in the DOM, leaving developers to hunt down the issue through visual debugging.

Compile-Time Error Detection

Now consider the equivalent Mirrow code:

circle { 
  at: (50, 50), radius: 30, fill: "red",
  rect { size: (20, 20) }  // ← Type error caught here
}
Enter fullscreen mode Exit fullscreen mode

Mirrow performs compile-time safety checks using an internal element index to detect invalid parent-child relationships. The compiler throws a descriptive error before the invalid structure ever reaches the DOM. This creates a seamless feedback system that helps developers write correct SVGs from the start.

Declarative Attributes

Mirrow introduces cleaner, more intuitive syntax while respecting the SVG specification. We've replaced ambiguous attributes like cx/cy and x/y with logical tuples:

// Instead of XML's:
// <circle cx="50" cy="50" r="30" />
// <rect x="10" y="20" width="50" height="50" />

// Mirrow uses:
circle { at: (50, 50), r: 30 }
rect { at: (10, 20), size: (50, 50) }
Enter fullscreen mode Exit fullscreen mode

The at tuple provides clear positioning that's instantly understandable, even to those new to SVG. This eliminates the confusion around attribute pairs while maintaining type safety.

All attribute changes are documented with their SVG equivalents for easy migration. The goal is straightforward: make SVG authoring more accessible without sacrificing power.

Type safety

Mirrow's type checking system validates your graphics before they run, catching structural errors and type mismatches that XML would silently ignore. The compiler understands SVG semantics, preventing impossible element hierarchies as mentioned earlier alongside ensuring attribute correctness.

For example, these errors are caught during compilation:

// Type mismatch: number expected
circle { at: (50, 50), radius: "thirty" }  // Error: expects number

rect { at: (10, 10) }                      // Error: missing 'size'
Enter fullscreen mode Exit fullscreen mode

This approach maintains full SVG compatibility while dramatically improving developer experience. You spend less time debugging rendering issues and more time building graphics that work correctly the first time.

The type system is at the current moment a work in progress. While it does address overarching value mismatch such as the aforementioned examples; it does not apply types to the context directly. We hope to improve these shortcomings in the future in order to implement full compile time safety.

Conclusion

Mirrow represents a shift in how we approach SVG authoring, from runtime guesswork to compile-time certainty. By bringing type safety and structural validation to vector graphics, it eliminates the silent failures and debugging sessions that have plagued developers for years. While traditional SVG tools focus on manipulating existing graphics, Mirrow ensures they're correct from the very first line of code.

This is just the beginning. As the compiler evolves to encompass more contextual awareness and smarter validation, we're moving toward a future where SVG bugs are caught before they're written.

Try it today with npx mirrow or visit our playground, and join us in building a better way to create for the web. The era of compile-time graphics has arrived.

Top comments (1)

Collapse
 
jos_pedro_e7f2cad30f5c28 profile image
José Pedro

That is a very efficient and cleaner way of writing SVGs altogether. Catching the errors and pointing it is really helpful and would save up a lot of time for building instead of having to figure out what's causing that failure, which can be really frustrating. The syntax will also help with that.
Mirrow is a great project and will make writing SVGs very much a more pleasant and rewarding experience!