SVGs and PDFs can both be interactive
SVGs and PDFs can both be interactive
Notes from my travels through file formats, June 2026
SVG and PDF both have a rarely-used interactive layer hiding in their specs.<br>SVG in particular can almost host small, fully contained apps. Did you know<br>this? I didn't until somewhat recently, and I haven't found a cohesive<br>treatment of the topic out there. So, here it is.
For some context, I've spent the last few years building Vexlio, a tool for exactly this: authoring and publishing<br>self-contained interactive documents. As a part of my somewhat obsessive nature, I spent a lot of time thinking about<br>how I was going to make Vexlio's interactive documents into things that could be saved and shared. Along the way I<br>learned that two very common formats, PDF and SVG, have a quite<br>uncommonly utilized part of their spec: programmability and interactivity.
You have probably come across an interactive SVG or two, and there are well-known projects out there leveraging<br>interactive SVG as their primary output format (for example, the excellent<br>Flamegraph<br>tool for performance analysis).
I doubt, though, that you've come across an interactive PDF. Not just text fields, but objects that respond to clicks<br>or keystrokes. If you have come across one, you probably didn't know it, because your PDF viewer opened the doc and<br>just omitted the interactive parts.
#Hiding in plain sight
At their simplest, SVG and PDF are both containers for vector-graphics content. SVG uses XML to specify things like<br>"place a red, 50x50 rectangle at position (100,100)." PDF uses an imperative, stateful language derived from<br>PostScript to say things like "switch color to red, place a pen down at position 100,100, drag pen right +100, ...".<br>Different models, same outcome.
At some point, maybe someone asked the same question of each format: how do we add just a little bit of dynamic<br>content, like a tooltip that shows up when you hover your mouse over this text/shape? I like to imagine the response<br>from the engineers in the room was something like, "well, if you really want to go that route..." while privately<br>groaning.
The problem is that "just a little bit" of dynamic content inevitably needs a system that expands into a complex<br>system of animations, timers, event callbacks, hit-testing.... And just such a system was spec'd and bolted on to each<br>format. Let's look at each one separately.
#Interactive SVGs
Here's a live example of an interactive SVG:
Download the SVG
Click around on the shapes, try dragging your mouse too. You can<br>download the .svg file, and you'll have a stable, interactive document that you can open in your browser, even offline.
The mechanism driving interactive SVGs is JavaScript embedded in the<br>file, relying on the viewer's JS runtime to route events, run timers, etc.<br>Typically you either associate named identifiers with specific elements in the<br>SVG and reference them by id in the embedded JS, or hook up event handlers<br>with markup in the XML element declarations. The example SVG above uses the<br>reference-by-id approach, e.g.:
owns positioning; the circle just owns its look. -->
and the embedded script:
const svg = document.querySelector('svg');<br>const group = svg.getElementById('dragGroup');<br>const circle = svg.getElementById('dragCircle');
function screenToWorld(e) {<br>const pt = svg.createSVGPoint();<br>pt.x = e.clientX;<br>pt.y = e.clientY;<br>return pt.matrixTransform(svg.getScreenCTM().inverse());
let dragging = false;<br>circle.addEventListener('pointerdown', () => dragging = true);<br>circle.addEventListener('pointerup', () => dragging = false);
circle.addEventListener('pointermove', (e) => {<br>if (!dragging) return;<br>const { x, y } = screenToWorld(e);<br>group.setAttribute('transform', `translate(${x},${y})`);<br>});
It turns out that this paradigm, a DOM that you can peek and poke at with sidecar scripting, is quite capable (you may<br>have heard of another use of this same paradigm, "the Internet"). Lots of charting libraries, for example, use<br>interactive SVGs as their stable output format. Taken to the extreme, I think you could implement most of a simple app<br>entirely in a single SVG file.
And there's actually another under-utilized (in my opinion, anyway) capability of SVGs when embedded in a web page:<br>they can be manipulated externally as well, and styled by the same CSS as the rest of the site. This opens up<br>a broad avenue of expressiveness, and is one of the real wins for a file format that's easily interoperable with the<br>rest of the web.
#Interactive PDFs
Now for the surprising part: PDFs can technically do (some of) this too. Here's a sample interactive PDF illustrating<br>the point:
Your browser does not appear to support embedded PDFs.<br>Download the PDF instead.
If you have Adobe Reader installed, the interactivity will likely work out-of-the-box. You may need to enable some<br>more permissive security settings in Reader in order for it to work. If you're not using Reader, some...