Create complex web apps with ease!
Imba is a new programming language for the web that compiles to highly performant and readable JavaScript. It has language level support for defining, extending, subclassing, instantiating and rendering dom nodes. For a semi-complex application like TodoMVC, it is more than 10 times faster than React with less code, and a much smaller library.
Imba.inspiration
Imba brings the best from Ruby, Python, and React (+ JSX) together in a clean language and runtime.
Imba.interoperability
Imba compiles down to clean and readable JavaScript. Use any JS library in Imba and vica-versa.
Imba.performance
Build your application views using Imba's native tags for unprecedented performance.
tag reminders < form
def onsubmit event
@list.append <li.reminder> @field.value
@field.value = ''
event.cancel
def render
<self>
<input@field placeholder='Remind me...'>
<ul@list>
Reusable components
A custom tag / component can maintain internal state and control how to render itself. With the performance of DOM reconciliation in Imba, you can use one-way declarative bindings, even for animations. Write all your views in a straight-forward linear fashion as if you could rerender your whole application on every single data/state change.
tag clock
prop utc
def build
schedule(fps: 30, events: no)
def turns div
let num = (Date.now/60000 + utc * 60) / div
return "rotate({(num % 1).toFixed(3)}turn)"
def render
<self>
<div.m transform=turns(60)>
<div.h transform=turns(720)>
<div.s transform=turns(1)>
<div.clocks> # spawn 4 clocks
<clock title='New York' utc=-5>
<clock title='San Fran' utc=-8>
<clock title='London' utc=0>
<clock title='Tokyo' utc=9>
Extend native tags
In addition to defining custom tags, you can also extend native tags, or inherit from them. Binding to dom events is as simple as defining methods on your tags; all events will be efficiently delegated and handled by Imba. Let's define a simple sketchpad...
let dpr = window:devicePixelRatio or 1
tag sketchpad < canvas
# receive the touch / click
# create two paths for each touch
def ontouchstart t
t.capture
t.data = [Path2D.new, Path2D.new]
# triggered when a touch moves
# loop through the paths and draw them
def ontouchupdate t
t.data.forEach do |path,i|
let x = t.tx + i + i * Math.random * 3
let y = t.ty + i + i * Math.random * 3
path.lineTo(x * dpr,y * dpr)
context('2d').stroke(path)
def render
<self width=(parent?.width) height=300>