a JavaScript library for building browser-hosted user interfaces

class Polygraph extends Component {
	bdElements(){
		return svg({width: 200, height: 200},
			svg("g",
				svg("polygon", {bdReflect_points: [this.kwargs.stats, pointsToPolyPoints]}),
				svg("circle", {cx: 100, cy: 100, r: 80}),
				e(Collection, {root: svg("g"), childType: AxisLabel, collection: this.kwargs.stats})
			)
		);
	}
}

See it in a Pen or in your browser

Does it look familiar? But Backdraft is dramatically different:

Small

~10x smaller than competing frameworks

Fast

faster than competing frameworks

Easy to Use

no compilation step required

Easy to Understand

zero dependencies

Declarative Composition

Backdraft's API includes declarative composition, but doesn't invent yet another markup language to do it...it's all done in pure JavaScript. Ask yourself, "do I instantly understand the example code?" If the answer is yes, then ask yourself another question: is using a markup language to express an application worth the cost in complexity?

A declarative, compositional API does not require a virtual DOM. The two concepts--how a program is expressed compared to how that expression is implemented--are orthogonal.

Backdraft does not employ a virtual DOM. This design decision results in several significant advantages. Teams are right to ask the question: is the cost in space, performance, and complexity of a virtual dom design justified?

dialogBody(){
	this.title = "Rename";
	return e("div", {className: "rename-dialog"},
		e("div",
			e(Labeled, {label: "Current Name"},
				e(Input, {
                    value: this.kwargs.currentName,
                    disabled: true
                })
			),
			e(Labeled, {label: "New Name"},
				e(Input, {
					bdAttach: "newName",
					value: this.kwargs.currentName,
					placeholder: "enter new name",
					style: "min-width:20em"
				})
			),
		),
		e("div", {className: "bottom-buttons"},
			e(Button, {label: "Cancel",
				handler: () => this.onCancel()}),
			e(Button, {label: "OK",
				handler: () =>
                    this.promise.resolve(this.newName.value)})
		)
	);
}

This is code from the rename dialog example.

Small Code Stack

Backdraft's code stack is about 2000 lines of pure, modern JavaScript with no dependencies. Backdraft is not new. It's been used in various incarnations in private, for-profit projects for over a decade. And during that time, Occam's razor has been continually applied. Backdraft is order(s) of magnitude smaller than competing solutions. And the cost of size is pervasive:

Big libraries cost more for engineers to understand--both the API, and, perhaps even more important, the side effects of using that API.

Big libraries increase debugging cost. Groking a couple hundred lines of library code to understand a defect is doable. Groking thousands of lines under the pressure of a delivery schedule is a completely different matter.

Big libraries cost more to download. This is particularly important--perhaps in terms of keeping customers--when targeting mobile platforms.

Big libraries are often computationally expensive. Once again, this is particularly important when targeting mobile platforms.

Backdraft is order(s) of magnitude smaller than the competition...

Backdraft
42 KB
Angular
1100 KB
Backbone
400 KB
React
1200 KB

Approximate kilobytes of downloaded code (application + library) for a small "todo" application. See the Backdraft example for details.

Backdraft applications never require more code and often requires less...

Backdraft
280 lines
Angular
280 lines
Backbone
300 lines
React
400 lines

Approximate lines of client code for a small "todo" application. Note that the Backdraft example is not as small as possible, but rather was built to demonstrate Backdraft's abstraction mechanisms and includes serveral, generic, reusable components built from scratch. These kinds of comparisons can be rigged: our point isn't that the competing frameworks are bad in this respect, but rather to demonstrate decreasing library complexity does not, ipso facto, result in increased program complexity.

Minimal Computational Complexity

Backdraft minimizes computational complexity and Backdraft's API design makes it hard to use incorrectly. Assuming no library design or library usage errors, it's hard to imagine any user interface library implying such computational complexity that the computational resources of an average computer would be stressed.

But there are three assumptions in that statement:

Libraries implementations are often overly complex and then used improperly because the complex implementation causes severe side-effects if used wrong. Paradoxically, libraries that employ complex designs to "simplify" usage are often the same libraries that are easy to misuse, resulting in new problems.

There is an obvious approach to controlling these risks:

Define an API that is hard to misuse; design and implement with simple algorithms.

For example, many modern JavaScript libraries rely on a virtual dom. Why? What, precisely, are the benefits of such designs? Is the computational complexity implied by a virtual dom design justified by its benefits? We think not.

And if virtual dom is great and the computational complexity insignificant, then why did the number one product in this space recently decide that it needed to replace it's implementation and provide proof that the new solution was, at least, better?

Backdraft applications are fast...

append

Backdraft
Angular
React
260ms
373ms
400ms

update

Backdraft
Angular
React
6ms
101ms
149ms

reorder

Backdraft
Angular
React
300ms
462ms
300ms

Approximate times for tests described in a simple benchmark for several javascript frameworks. The Backdraft example tested can be found here. These times show order of magnitude comparisons; they are not intended to show high-precision times.

All the Normal Requirements

Baseline requirements aren't particularly interesting. But, they are requirements nevertheless. Backdraft fulfills them.