Building Web Apps with Tram-One

A complete, consistent, and friendly view framework

Instructions on getting your own FREE Tram-One stickers at the end of the article!

Over the past year I’ve been working on a new javascript view framework, Tram-One. It’s something that I’ve really enjoyed working on, and working with to build powerful web applications!

Now, there are those of you who already have a framework of choice, who love and enjoy working in those frameworks, and are really productive in those frameworks. There are some of you who are familiar with a framework, but don’t know all the ins-and-outs — you can work in a project, but defer to someone else’s defaults or generator when it comes to building a new project. And lastly, there are some of you that probably find the whole thing too confusing, and don’t want to learn a whole new way of writing HTML and javascript just to tie a button to an input.

Tram-One is a meaningful option, regardless of where you put yourself on this scale. Tram-One is a view framework that is complete, consistent, and friendly to learn and write.

I’ll go into each of these in more detail as we go over a tiny web-app, which will hopefully give you a more complete picture of what makes Tram-One unique.

The web-app we will be going over is a simple Binary Clock. To see the source code, go to

You can see the app live here:

First let’s look at the smallest component in Tram-One, a view element.

A view element at it’s root is a function, that takes in attrs (attributes like href, src, or in this case size and on), and return some DOM. This DOM is built with an html function that Tram-One provides. In this instance, our DOM isn’t that crazy, it’s just a div, with some height and width, and a background color.

This is a key feature that makes Tram-One consistent with HTML. Unlike other view frameworks which treat components like heavy objects with event management and handler definitions, view elements take in attributes (and children, not shown here) exactly like standard DOM.

Let’s take a peek at how we use this led.js with the digit element (a single column of leds that display a single “digit”).

Here we see led.js referenced in the top html() function, and then used in the template that we return.

The magic here is that we can use led as a tag, just like any other tag we could use from HTML, and we don’t need to use special syntax/file format to achieve this either. This makes Tram-One friendly for composing multiple elements in a pure JS environment. It’s easy for us to use lots of elements, with a similar interface to HTML, and build complex UIs without re-learning how to write HTML, or a different kind of Javascript.

It’s not enough to show any random digits though! We need to show the current time, and to do that, let’s go into actions and how the clock uses that to display the latest time.

Each reducer has actions that keep track and update a store that is available to Tram-One views. In this case, we have a store.clock and a store.ticker, as well as a actions.tick(), and actions.startTicking(delay). If you are familiar with redux, this pattern should be familiar, and is powered by Hover-Engine.

Here we have 2 different actions reducers, one that keeps track of the current time, and one that is responsible for triggering the tick action at an interval. One thing you might notice is that we’re able to trigger an action here in our startTicking function. This actions.tick() will actually trigger the clock.js tick action and update the value of the store to the latest time, also triggering a re-render.

The wiring here makes Tram-One complete, with its own reducer and sub-action triggering. Whereas other frameworks depend on generators for getting started, Tram-One has powerful state management (and routing, not shown here) baked in for free, making it more friendly for jumpstarting a new app!

For completeness sake, we’ll show the last three files, which are the clock view component, the home page, and a main configuration file that wires our actions and routes to our app.

main.js includes basic configuration, and details webEngine: window.engine which lets us describe a global object that our components can pull from.

In home.js we check if the clock has already been started, and trigger it if we need to. While we could pass the store value to the clock element here, we have the option to pull that value in clock.js itself from

The Past and Future of Tram-One

Tram-One is a project that I started after stepping out of the React world and trying other view frameworks. I stumbled upon choo, a view framework that emphasized user friendliness and a small api.

Using choo made me reconsider what web apps needed to look like, and taught me a lot about javascript development. I hope that Tram-One in a similar way can help developers - who are hardened React veterans, or just starting out - learn a new way of building web apps that’s excited and new, complete out of the box, and most of all, friendly and fun!

If you would like to read the entire API, how to get started, and other links, check out

If you would like to start doing Tram-One development, and score some sweet sweet free stickers, create an app with Tram-One, make a PR to add it as an example, and join our slack!