How to make interactive, code-based prototypes that feel like the real deal, even if you suck at JavaScript

Snowy alpine peaks

You want to make a high-fidelity prototype. And you want to make it quickly. It should be easy to share, suitable for usability testing on multiple devices (responsive), and allow for real interactions and animations.

A Figma or Sketch prototype doesn't feel real enough. There are all sorts of interactions and logic in the product. You want to be able to add an element into the page flow (e.g. push other items downwards), without creating hacks and dozens of artboards for each little variation.

You want to give your users real form controls to test out your design.

Other prototyping tools such as Framer are useful for page transitions and interactions. But these tools fall short for getting user input.

Apps such as Webflow are an option for creating web-based prototypes with real interactions. But with Webflow you're learning the tool rather than how to code. This might work for some people, but I prefer to use the tools of the web – HTML, CSS and Javascript. There are also other reasons I prefer working in my code editor – for example, you can pull in CSS directly from your design system or production app.

So, what to do then?

Make a code-based prototype! It'll be responsive, interactive and realistic. Real enough to feel like you're interacting with the real product. It'll be better than whatever else you were going to do.

You might be a HTML and CSS guru. If so, coding a page layout is your bread and butter. And yet the JavaScript interactions always slow you down. JavaScript isn't your strong suit, and that's OK. But it stops you from really feeling productive in code.

I just want to make a hamburger menu open and close when the user clicks it!

Dropdowns, modals, hamburger menus, tabs. The building blocks of modern app UIs. These are frustratingly slow to prototype and iterate on using traditional design tools.

But you can easily make these interactive in Javascript for your code-based prototypes. Yep, even if you think you suck at it.

What are your options for using Javascript in a code-based prototype?

  • jQuery: By all means use jQuery if you can work quickly with it. But I find jQuery's imperative style of coding slow for prototyping, as you are writing the JavaScript code in a different place to your HTML.
  • React, Vue: Great for large apps, but overkill for design prototyping. The large learning curve of these full-featured apps can put off designers who just want to show simple state changes.
  • Vanilla JS: The verbose nature of vanilla JavaScript means it's not well-suited for beginners for prototyping purposes.

I've used all of the above, and none of them felt right for rapid prototyping. I want to get interactions working quickly so I can get back to focusing on the design problems.

Say hello to Alpine

Alpine JS is a small JavaScript library that's perfect for designers making prototypes.

A rugged, minimal framework for composing JavaScript behavior in your markup – Alpine docs

With Alpine, you create your JavaScript behavior right in your HTML. Perfect for interactive elements where you're generally toggling classes to show and hide elements on the page.

Some benefits to Alpine over the common alternatives like React or Vue:

  • No build steps. It's one script tag. Get started right away. (Yes I know React and Vue can also be used this way, but they still have other drawbacks such as being harder to learn and needing more code)
  • Learn the parts you need in a few minutes.
  • Handover to developers is easy. The behavior is right there in the HTML.

Getting started with Alpine

Add the following script to the end of your <head> section of your HTML page.

<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>

That's it. It will initialize itself.

A dropdown menu

The CodePen examples use Bulma for styling. Bulma doesn't have any JavaScript, so it's perfect for trying out Alpine JS. Most of this markup is straight Bulma, with some Alpine JS added to make it work!

The Bulma dropdown docs explain that the dropdown menu wrapping div needs a class of is-active when the menu is open. We can use Alpine to do this.

See the Pen Dropdown in Alpine JS with Bulma for styles by Jed Lehmann (@jedlehmann345) on CodePen.

  • The state: you need a wrapping element to hold your state. In this case it's the div with x-data="{ open: false }". Open is set to false as the default. This means the menu will be closed when the page loads. x-bind:class="{ 'is-active': open }" means that when the state is changed to open, the class is-active should be applied.
  • The button: The button needs a click event to change the state to open. This is done with x-bind:class="{ 'is-active': open }" @click="open = true".
  • The menu: We want the menu to close when the user clicks outside it. We do that with @click.away="open = false".

And that's it. Add a few Alpine statements to your HTML and you've got an interactive element.

A more detailed example you can experiment with

Below is a CodePen with three interactions:

  1. Hamburger menu open and closing.
  2. Modal open and closing.
  3. Navbar change on page scroll.

See if you can find the Alpine JS parts to understand how each of the three items works.

See the Pen Alpine JS with Bulma by Jed Lehmann (@jedlehmann345) on CodePen.

Feel free to fork this example and play around with it! You could try and integrate more of the Bulma components with Alpine!

Some resources for helping you learn Alpine

  1. Check out the Alpine docs. This is the best place to learn Alpine. They have an example of tabs, so you could try to use this reference to make a tabs component using Bulma tabs.
  2. Alpine Toolbox has some great examples. Many of these examples use Tailwind.css so it's all right there in the HTML, no CSS or Javascript outside of the HTML. This makes them very portable, so you can copy and paste them directly into your project.

The freedom to experiment

Give Alpine JS a shot next time you want to make a code-based prototype with realistic interactions. It's easy to use, which gives you the freedom to experiment.

You might fall in love with the power and simplicity it can give you.