Introduction to Tonic - the component framework
Tags: tonic, javascript, framework, tutorial
Published: 2022-03-25 01:49:08

by [Ikey Akinyemi](https://blog.openreplay.com/authors/ikeh-akinyemi)

Front end development changes frequently as frameworks spring up rapidly. Tonic is a front end framework that emerged in the last two years and is great for developing JamStack sites due to its small file size (5KB), making a good choice for websites with great load time. Using libraries to build high-performing web applications has become vitally important, front end frameworks and libraries have become an important aspect of web development.

In this article, we’ll discuss Tonic, a component-based framework that allows front end developers to create incredibly quick and beautiful user interfaces, as well as its properties, capabilities, use cases and its advantages over other component-based frameworks for building JAMstack sites. At the end of this article, readers will have an understanding of what Tonic is, how to use it when styling user interfaces, and also for handling events. This will enable them to build UI components without the use of any additional build tool or complexity. Also, we’ll demo a sample Tonic project on building our first functional component Tonic component.


## What is Tonic?

[Tonic](https://tonicframework.dev/) is a stable and minimal component-based framework that enables front end developers to build blazing-fast JAMstack sites with amazing UI. It is a server-side rendering by default, it also uses event delegation by default and doesn’t require any build tool. It is a framework that enables you to write async web components.

Tonic leverages CSS variables to theme components which allow developers to use any CSS framework of their choice. This makes Tonic a design system(for building UI) and a web component framework. It has good examples of components built with Tonic in a [](https://github.com/optoolco/components)[separate repo](https://github.com/optoolco/components) available for use.

## Prerequisites

You do not need to have any previous knowledge on Tonic before this article, however, it’s a plus if you are familiar with any component-based framework. You’ll need to be familiar with:

- Basic JavaScript because Tonic is a JavaScript framework
- Basic HTML and CSS.

## Getting started with Tonic

To use Tonic, you have to import it:

```javascript
import Tonic from '@socketsupply/tonic'
```

Creating components in Tonic is similar to writing components in other component-based frameworks like React and Vue. To build a component in Tonic, you have to create a class or function. The class must have one method(at least) called `render` which returns a template literal of HTML.

```javascript
class MyGreeting extends Tonic {
  render() {
    return this.html`
      <h1>Hello World</h1>
    `;
  }
}
```

After creating a component, we need to add the component to Tonic.

```javascript
Tonic.add(MyGreeting)
```

Next, you need to add your JavaScript file to your HTML.

```
<html>
  <body>
    <my-greeting> </my-greeting>
    <script src=”app.js”></script>
  </body>
</html>
```

Once you have successfully added your JavaScript file to your HTML, then you can use your component anywhere. Please note that custom tags (like `my-greeting`) require a closing tag even if they have no children.

## Properties

If you have used other component-based frameworks like React, you should be familiar with props.  Props are properties passed from one component to other components via HTML attributes. Props are passed to the component in the same way arguments are passed to a function. 
When you add properties to a component, they appear on `this.props` object. Tonic uses `this.html` to pass complex values to a component. 
The `.reRender()` method is used to manually update a component’s property, this method takes either a function or an object as an argument. The reRender method can also be called directly on a component.

```javascript
this.reRender((props) => ({
  ...props,
  name: "John",
}));
```


## Why Tonic?

There’re many advantages in using Tonic for your JAMstack applications over other popular frameworks like React and Vue.js.

A key reason why Tonic is ideal for building JAMstack sites is because of its size. It is only 5KB with 350 lines of code which makes your web application load faster. Tonic also doesn’t require any dependencies, build tool or rendering engine installed on the server-side.

Also, your component names can be viewed in the browser’s DOM of your website which makes it easy to debug production code. You also get the same developer experience as from other modern component-based frameworks. 

## UI styling in Tonic

Tonic is a framework that allows front end developers to create incredibly quick and beautiful user interfaces, it supports multiple approaches for styling components. We’ll go through the three approaches in styling Tonic components:

*Inline styling*

Just like adding CSS inside your HTML, we can add inline styles to any Tonic component we want to render. Tonic provides the `styles()` method that helps you safely inject inline styles to an HTML element.

```javascript
class MyStyle extends Tonic {
  styles() {
    return {
      a: {
        color: blue,
        fontSize: "30px",
      },
    };
  }
  render() {
    return this
      .html`<p styles="a">${this.children}</p>`;
  }
}
```


*Dynamic stylesheet*

We use the `stylesheet()` method to add a dynamic stylesheet to our component. This way we can change an element dynamically in response to user events.

```javascript
class MyStyle extends Tonic {
  stylesheet() {
    return `
          my-style p {
            color: ${this.props.color};
          }
        `;
  }
  render() {
    return this.html`<p></p>`;
  }
}
```


Then in our HTML file:

```
<my-style color=”blue”>Hello World!<my-style>
```

*Static styling*

The static `stylesheet()` method is used to add a stylesheet to the document only once. The style is fixed and doesn’t change while the application is running, they are not dynamically generated. 

```javascript
class MyStyle extends Tonic {
  static stylesheet() {
    return `
          my-style p {
            color: red;
          }  `;
  }
  render() {
    return this.html`<p></p>`;
  }
}
```

## Open Source Session Replay
_Debugging a web application in production may be challenging and time-consuming. [OpenReplay](https://github.com/openreplay/openreplay) is an Open-source alternative to FullStory, LogRocket and Hotjar. It allows you to monitor and replay everything your users do and shows how your app behaves for every issue. It’s like having your browser’s inspector open while looking over your user’s shoulder. OpenReplay is the only open-source alternative currently available._

![replayer.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647097041609/Qi6sMOaaB.png)

_Happy debugging, for modern frontend teams - [Start monitoring your web app for free](https://github.com/openreplay/openreplay)._

## Tonic’s component state

A component can be one of two types. It can be either a function component or a class component. 

`this.state` is a plain-old javascript object whose value is persisted if the component is re-rendered. The state is a built-in object used to store data of the component that is to be rendered. Any component that uses state must have an `id` property.

## Creating your first component

Now let’s build a simple functional Tonic component. This project will be created in code pen.
In this project, we will create a button that generates a random number from 1 to 10 whenever we click the button. This short demo will also introduce you to event handling and methods in Tonic.
First, we need to import Tonic, let’s add the following code in the JavaScript file:

```javascript
import Tonic from "https://cdn.skypack.dev/@socketsupply/tonic"
```

Once we have successfully imported Tonic, then we can go ahead to create our first Tonic component. 

In Tonic, web components require a name with two or more parts. So your class or function name should be `CamelCased` (starting with an uppercase letter). For example, `RandomNumber`  becomes `<random-number></random-number>`.

```javascript
class RandomNumber extends Tonic {
  constructor() {
    super();
    this.state.counter = 0;
  }

  click(e) {
    const trigger = Tonic.match(
      e.target,
      "button"
    );
    this.state.counter = Math.round(
      Math.random() * 10
    );
    this.reRender();
  }

  render() {
    return this.html`<p>Random Number ${
      this.props.name
    }: <button>${this.state.counter.toString()}</p>`;
  }
}

Tonic.add(RandomNumber);
```

The state object is initialised in the constructor. The constructor is a special method that is called once each time an instance of our component is created. Then we create and set the counter variable to zero. 

The click event as you might have known is used to listen for clicks on the component. This is because we want the random number to be generated only when the button is clicked. 
Tonic prefers the [](https://davidwalsh.name/event-delegate)[event delegation](https://davidwalsh.name/event-delegate) pattern to attach a single event listener rather than using multiple event listeners. Each event handler method will receive an `event` object that contains a `target` property, to target the exact element that was clicked. An event handler can be attached in any component.

Just like in React, we need a `render` function on the class that returns the inherited function `this.html`. This `render` function accepts a template literal containing the HTML element to be rendered. It can also render dynamic values. For example, `name` is a property of the component `*<random-number>*`  with the value of the `name` set to `"generator"`, it is accessed with `this.props.name`.

Lastly in our JavaScript file, we need to register our component with Tonic using `Tonic.add()` method.

Now we need to add our created component as an HTML element in our HTML file after we have linked our JavaScript file in our HTML. We added an `id` because as stated earlier, any component that uses `state` must have one.

```
<body>
  <random-number name="Generator" id="count"></random-number>
  <script src="index.js"></script>
</body> 
```

That’s it. We have created our first functional Tonic component. 


![Our first functional Tonic component](https://blog.openreplay.com/static/ca8ab92efd4f7f9afd533494b160c71a/990ff/image1.png)


Here’s a link to the code-pen to see exactly how it works: [](https://codepen.io/dalu46/pen/ZEvzKoM)[https://codepen.io/dalu46/pen/ZEvzKoM](https://codepen.io/dalu46/pen/ZEvzKoM)

## Conclusion

We’ve just scratched the surface of Tonic learning about its properties, event handling, component and a few others. Tonic offers the same developer experience as other component-based frameworks like React, the class approach is similar to writing class components in React. Smaller than other components in size, it makes your site load faster. Building your next static site, consider making use of Tonic to get a feel/experience of what building with it feels like.