🔙 All posts

On Embedding Code Editors in Posts

Where I build a worse version of JS Fiddle


Planted November 24, 2023

A while ago, I posted on Twitter (still calling it that) wondering if there was prior art I could look to for embedding code editors in posts. I was thinking of something like JS Fiddle, but for Markdown.

I got one reply to look at Josh Comeau’s blog. I love Josh’s blog and the interactive elements in his posts are an inspiration. That’s one of the reasons I wanted to move my blog to MDX, so I could do the same.

I’m not (yet? growth mindset!) as visually creative as Josh and I wanted to see if I could build something that would work for me. I also wanted to see if I could build something that would work for other people.

The Idea

I wanted to be able to write a post like this:

<CodeEditor
  initialCode={`const add = (a, b) => a + b;
    add(5, 2);
  `}
>

And have it render like this:

And I kind of have that:

So, it works. But it’s not great and this post is pointing out some of the things I’ve tried and the things I want to improve.

What I’ve Tried

CodeMirror

I started with CodeMirror. It’s a great editor and I’ve used it before. It’s also the editor that powers JS Fiddle. I thought it would be a good place to start.

The problem I had was I’m using Preact to build the interactive components on this site at the moment. Using Astro, I could use Vue, Svelte or React and maybe I’ll try those in the future. But for now, I’m using Preact.

I could get CodeMirror to render but I couldn’t quite work out how to share the state between the editor and the parent component. I’m sure it’s possible and if I can get that to work it’ll probably replace the component I’m using now.

Monaco

This is the editor that powers VS Code. I had a look at this and it looks like it might be a good option but it was a bit more complicated than I wanted to get into at the moment. I’ll probably come back to this in the future.

From Scratch

This is largely where I’ve landed. I’m capturing the user input on the left-hand side and evaluating it to get the right hand side. This is the code I’m using:

useEffect(() => {
  try {
    const result = eval(code);
    setDisplay(result);
  } catch (e) {
    if (e instanceof Error) {
      setDisplay(e.message);
    }
  }
  }, [code])

It’s hardly rocket science but has started the journey.

What I Want to Improve

There are a lot of things I want to improve. I’m going to list them here and then I’ll come back and update this post as I make progress.

I want to be able to:

For some of this, it might work better to embed a Codesandbox instance - I don’t know. I’ll keep experimenting and see what I can come up with.

Conclusion

This is a work in progress. I’m trying to build up a toolkit of education interactive components. I’d love to get these to place where they were useable by other educators but I’m not there yet.

What other components do you think would be useful? Let me know on Twitter or in any of the socials below.

Like what you see?

I send out a (semi) regular newsletter which shares the latest from here and my reading from around the web. Sign up below.

    Your next read?