How To Animate Code Using TypeScript 🪄
Chapters4
The video demonstrates how to achieve smoothly animated code blocks using Shiki Magic Move, showing a simple view with a toggle that animates the transition and the option to display line numbers.
Learn to animate code blocks with Shiki Magic Move in a framework-agnostic TypeScript setup, using Shiki for syntax highlighting and a diff-based renderer for smooth transitions.
Summary
Joy of Code’s video by the creator demonstrates a framework-agnostic approach to animating code blocks using Shiki Magic Move. The method relies on Shiki for syntax highlighting and a dedicated magic-move core that diffs code to drive transitions. You’ll see how to set up a simple Vite + TypeScript project, import createHighlighter from Shiki, and wire in Shiki Magic Move’s core and renderer. Joy of Code emphasizes copying essential styles from the Shiki Magic Move repo to ensure animations render correctly. The tutorial also covers toggling between the pre-change and post-change code, plus options like line numbers, duration, and staggered transitions. If you prefer JavaScript over TypeScript, you can skip the types while still getting the same animation experience. Finally, the video teases deeper dives into how Shiki Magic Move actually works in a future tutorial, promising even more detail on the internal mechanics.
Key Takeaways
- Shiki Magic Move and Shiki are the two packages you need to animate code blocks in a framework-agnostic setup.
- The workflow uses a highlighter created with Shiki, then a magic-move machine diffs the code and a renderer applies DOM updates with animations.
- You must copy and paste the specific styles from the Shiki Magic Move repository (font, transitions, item selectors) for the animations to work.
- The example toggles between a 'steps before' and 'steps after' state to drive the animation via update calls on the machine.
- Stagger options and a chosen easing (like a linear ease) can be enabled to make transitions feel more natural and less uniform.
- TS shorthand like TS for TypeScript can be used for autocompletion and a smooth DX experience.
- If you want a non-TypeScript variant, the same approach works with plain JavaScript without losing functionality.
Who Is This For?
Frontend developers who want elegant, frame-agnostic code animations and are comfortable wiring up a small TypeScript project. It’s especially valuable for those using or evaluating Shiki for syntax highlighting with animated transitions.
Notable Quotes
"Hey friends, in today's video I'm going to show you how you can have smoothly animated cold blocks using shiki magic move."
—Opening claim of the tutorial and the core feature: smoothly animated code blocks.
"All right so here is the library in question. As it says, Shiki magic move is a low-level library for animating cold blocks and uses Shiki as a syntax highlighter."
—Defines the library and its purpose, tying Shiki to animated blocks.
"The only packages that you're going to need is Shiki Magic Move and Shiki itself."
—Highlights the minimal dependency setup for the framework-agnostic approach.
"You copy paste some styles from Shiki magic move. So if I open the style CSS here I have some basic styles."
—Emphasizes a crucial step needed for animations to render correctly.
"Here's also a cool part. So this uses the actual VS Code team grammar. So you get actual great lookings when using syntax highlighting such as my favorite team, PO Manress."
—Notes on VS Code grammar and specific color themes used for highlighting.
Questions This Video Answers
- How do I set up Shiki Magic Move in a TypeScript project from scratch?
- What are the essential steps to animate code blocks with a framework-agnostic approach?
- How does the diff-based machine in Shiki Magic Move determine code changes for animation?
- Can I enable staggered transitions and custom easing with Shiki Magic Move?
- What styles are required from the Shiki Magic Move repo to enable animations?
Shiki Magic MoveShikiShikiJSTypeScriptsyntax highlightingcode animationdiffing machinerendering transitionsStaggereasing functions
Full Transcript
Hey friends, in today's video I'm going to show you how you can have smoothly animated cold blocks using shiki magic move. So on the right we have a simple view example and when I press toggle examples it should smoothly animate. How beautiful is that friends? And if you want you can also have line numbers of course and under the hood this uses the shikjs syntax highlighter. All right so here is the library in question. As it says, Shiki magic move is a low-level library for animating cold blocks and uses Shiki as a syntax highlighter. But it also says that you usually want to use it with a highlevel integration or one of these framework rappers for view react or swelt.
So for example, if we look at the swelt example here, we can see that it's really simple. We can just import chicky shiki magic move and then we can import the styles here. We create the shiki highlighter. Then we have our code and then we can use this component where we pass props like the language theme including the options. But in this video I actually want to show you how you can use Shiki magic move framework agnostically and it's really simple to set up. The only packages that you're going to need is Shiki Magic Move and Shiki itself as you can see right here.
But if you're interested I'm going to link to a video where I show you how you can use the swelt wrapper for Shiki Magic Move. But in today's video, I'm going to show you how you can set up a framework agnostic solution using TypeScript. But of course, if you don't care about types, you can just use JavaScript. All right, friends. So, I created a simple V TypeScript project. And if you want to look at this code later, I'm going to put the link to the blog post in the description. As you can see, we're just importing create highlighter from Shiki and some types.
And then from Shiki magic move/core, we're importing code to key tokens and create magic move machine. This is basically going to diff the code and find the differences in it. And then later we need to construct the DOM and do the transitions using magic move renderer from Shiki magic move/ renderer. And here is the most important part. We need to copy paste some styles from Shiki magic move. So if I open the style CSS here I have some basic styles. You can ignore this. It's not important. The only important part is this. So here I added some font family and font size.
You can ignore this but you need to have all of these styles here. And then you need some other styles for Shiki magic move. Search for the item, the transitions and etc. And you can find all of these styles in the Shiki magic move repository. So don't forget the crucial step otherwise your animations aren't going to work. All right. So back in our code, I just have some types here where I created an interface. It's really not important. So here's the important part. First, we need to create the shiki highlighter. So we can say await create highlighter and then you can pass the language that you want.
So for example, we can use the shortand TypeScript and you get great autocomp completion. So this is super simple. So you can have TypeScript, JavaScript, well, whatever you need. So you can set this up here and that's basically it. And of course, here's also a cool part. So this uses the actual VS code team grammar. So you get actual great lookings when using syntax highlighting such as my favorite team, PO Manress. But of course, there are other favorites like Kpuchin. So you can have Katpuchin if you want or you can even create your own custom teams if you read the ShikyJS documentation.
But yeah, that's pretty cool in my opinion. All right, so here is where we're going to create the magic move class. So we're going to have these two fields, machine and the renderer. So as I already said, the machine divs the code and the renderer creates the DOM elements and transitions. So here we have the constructor. So we're going to pass the target highlighter, the initial code it should render, and the magic move options. So we're just going to dstructure these options here such as language, beam, and line numbers, which we're going to set by default to false.
But of course, you can do this however you want. If you don't like classes, you can use a function. All right. So, here we're going to create and add the pre-element. The only important thing is that this class name is Shiki magic move container because we're targeting it in the styles. And then we're going to append the pre-element to the target. And that's basically it. All right. So, here is where we create the Shiki magic move machine. So, we just need to say this machine equals create magic move machine and then we get this call back with a quote.
So, we have to use this function code to keys tokens. So this is going to turn our string into tokens and of course we need to pass the highlighter code language and the theme and if you want the line numbers alongside the options for create magic move machine. All right. So now that we created the machine we can create the renderer. So we can say new magic move renderer. We're going to pass the precode and then we're going to also pass the options. And here is where we're going to do the initial render. So we just need to call on the machine this machine.
We're going to pass the initial code and then we can say this renderer render and we're going to say this domachine.curren and the only thing left on the class is this update function. So this is how we're going to update the code. So we're just going to pass the code as a string and we're going to do the same thing this machine. And then we're going to say this renderer. This machine current. All right. So we're going to query the target element which in this case is app. And then here I have some steps with before and after.
and we need to push this code to the edge because of formatting. So I'm also using trim here, but of course if you want you can create a helper function that's going to help you with indenting the code. So here's an example how I do that in any motion using this indent function. It's just a simple function that removes any unnecessary tabs. All right, so now we can create our new magic move machine where we pass in the target highlighter and the steps before for the initial render. So here we have a couple of options.
So again we can pass the language instead of TypeScript we can use the short hand TS for the team I'm going to use PO manress line numbers by default and we can also pass the duration and we're going to look at some of these options in a bit but the only thing that we're doing is we're defining this toggle variable and then we have an event listener on the document. So when we click on it we're just going to toggle the code. So we're going to show the steps before or steps after using our code.update method and then we're just going to change toggle.
So here we have our beautiful code example and now it should smoothly animate. How beautiful is that friends? All right. So let me show you some other options. So you can see for example when we transition this code it happens all at the same time. But what if you want a nice stagger? So let me show you how that looks like. All right. So I'm going to go here. I'm going to enable stagger. And if you want we can also hide the container styles so you can match your theme better. So let's do that. And then we can also specify a custom easing.
So we can use this linear easing. And if you're wondering where I got that from, you can visit this linear generator and you can just copy and paste the code yourself. All right. So now our example looks like this. All right. So we're going to see that it has more character and because of the stagger, the transition doesn't happen instantly. So let me show you this again. That's really fun. All right, that's it. I hope all of this made sense. But if you need more information, you can watch my other video. And in the next video, we're going to dive deep into how Shiki Magic move itself works.
So, thank you for watching and catch you in the next one.
More from Joy of Code
Get daily recaps from
Joy of Code
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.









