Composi is a new library for creating components. These can be stateless or stateful. They use a virtual dom to know when to update the real DOM. You can use JSX or a hyperscript function for defining component markup. Composi supports scoped styles. You can use inline events or delegated events. You can create a component as an instance of the Component class, or extend Component to create a new, reusable component class.

You can check out the source code on Github. The docs explain everything you need to get up and running quickly. Because the library is small and focused, the API is concise. There is not a lot to learn. If you already have experience using JSX or Hypersrcipt, you’ll be productive in a hour or two.

So, why Composi and not some other library? As we mentioned, it’s small. Minified the core is just 7KB, 3KB when gzipped. That means it loads quick. It also means the largest part of the code to load will be code you write. It also renders HTML really fast. And it’s flexible. You could use it with jQuery, Lodash, Ramda, Mobx or any other library out there. It works on browsers all the way back to IE9 on Windows 7. Because it loads quickly, it’s a great choice for a progressive web app or a hybrid app. Because its API is very focused, there isn’t much to learn. In an hour you can be making things. Seriously. This is not going to take months of your life away, like Angular and React.

Installation

Time for action. First up you need to install it. I’m assuming you’re familiar with NPM. Open your terminal and run the following:

npm i -g composi

That’ll give you the composi command line tool. When it’s done, you can create your first project. You do that in your terminal as well. You use the -n flag to indicate the project name. If you want a multi-world project name, you’ll need to enclose it in quotes

composi -n MyProj

When this is done you’ll get a message in the terminal. It says you need to use the terminal to cd to the project folder and run:

npm i

Building

This will install all the project’s dependencies. These include Babel so you can write modern ECMAScript 2015 code and transpile it down to ES5 for older browsers. It also includes Uglifyjs and Browsersync. If you look in the project, you’ll find a dev folder. That’s were you’ll be working. When you build, its contents will get bundled and compiled and then loaded into your default browser. Building is easy. Just run:

gulp

Creating a Component

Open up the app.js file in your project’s dev folder. You’ll see the following:

Notice how at the top we import in h and Component from Composi. Whether you are going to use h for hyperscript functions or plan to use JSX, you need the h function imported. That’s because a Composi project is set up so that Babel will pass the transformed JSX through this function. Internally Composi uses it to create DOM nodes. We need to import Component so we can create components.

On line 3 you can see how we create an instance of Component. We pass it an object literal with some options: root, state, render and styles.

Root

Root is the DOM element into which the component will be rendered. This might just be the body or just about any other element on the page. It doesn’t matter. It’s totally up to you how to structure the HTML. In the above case we are telling Composi to insert the component in a header tag.

State

You use the state property to set state for your component. State can be a string, number, boolean, object, or array.

Render

The render function is how you define what HTML the component will create. Normally you’ll be passing the render function some data to use to create HTML. But you could also create a component that doesn’t take any data because it returns static HTML. Use a parameter that makes sense for what you are rendering. Above we use message . Because this is JSX, we’re enclosing it in parens. To interpret the data, we use JSX curly braces to enclose the variable.

Styles

The styles property lets you define styles scoped to the component. Because this is a JavaScript object, you need to convert properties and values into a format that is valid as an object. I don’t want to get into too much right now, but you can read more details about styles in the docs.

Making it Happen

And finally, to get this component into the DOM, we run:

title.update()

That’s it. What to change the message for that Hello World? Easy. Set the component’s state to the new value:

title.state = ‘Joe’

This will cause the component to create a new virtual dom and patch the current DOM with the new value.

Hello World

And here’s a Codepen example of Hello World:

Object Data

If you want to render an object of data, just use data notation to access the object properties:

In the above example you can see that it is easy to access the properties of an object in the render function markup. Here’s a Codepen version of this example:

Arrays

Many times you will need to create a list from arrays of data. An array can be primitive data types like strings and numbers, or it could be an array of objects. Regardless, having a render function use an array is straightforward. You use a map on the array to return the array item wrapped in markup. You’ll need to enclose the array variable in curly braces. Notice how we do this below:

Here’s a Codepen example of this:

If the array were of objects, you would access the object properties in the map function markup the same as for a single object:

Managing State

As we saw earlier, when a component’s state is a primitive type like a string or number, we can set it directly with assignment:

// Update a string value:

title.state = 'Woohoo!' // Update a number value:

age.state = 100

With this knowledge, let’s revisit our Hello World example and make it so we can update the name:

However, when a component’s state is an object or array, this kind of assignment won’t work. When a component’s state is complex, you can use its setState function. For objects, you simply pass in an object with the property and value you want to update. Let’s revisit the person object component and do an update:

const personData = { name: {

first: 'Joe',

last: 'Bodoni'

},

age: 26,

job: 'mechanic'

}

If we wanted to update the person component, we can use setState like this:

// Update the job:

person.setState({job: 'Web developer'}) // Update the first name:

person.setState({

name: {

first: 'Saul',

last: 'Bodoni'

}

})

Notice that in the case of the name property, we had to include first and last . This is because for objects, setState does a mixin. That means the name properties with first and last names would be replaced with a name of only first. If this type of object manipulation is too hard for you to keep track, just get the state object from the component, make your updates to the object and reassign it to the component’s state:

// Get the component's state:

const state = person.state // Update the first name:

state.name.first = 'Saul' // Assign new state to component:

person.state = state

If the changes you need to make to a state object are complex, it makes more sense to get the state, transform it and then reapply it to the component.

Updating an Array State

Updating an array state of a component requires one new value, the index in the array you wish to update. Let’s look at a simple array.

const fruits = [ 'Apples', 'Oranges', 'Bananas', 'Strawberries']

We used this on a component. But then we realize that Bananas should be Grapefruit . Since its index would be 2, we can update the fruit component like this:

// Update state array index 2 from Bananas to Grapefruit:

list.setState('Grapefruit', 2)

Now if the array contained objects, it would make for sense to just grab the state from the component, make the changes and reassign it to the component. For example, let’s assume we have a list of people, so the state is an array of person objects. We want to update the first name of the 5th person:

// Get component state:

const state = list.state // Update first name of 5th person:

state[4].name.first = 'Tom' // Reassign to component:

list.state = state

This was a quick introduction to how Composi works. You can also create more powerful components by added events or by creating a new component class by extending Component. We’ll look at these in future articles.

Here’s a Codepen example of update a component list array state:

Read the Documentation

Learn more about Composi by reading the documentation.

Here are a couple of Codepen examples that show a bit more advanced usage: