Cleaner code

ConstraintJS enables constraints — relationships that are declared once & automatically maintained. These constraints can make writing dynamic apps easier.


ConstraintJS is small (about 10kb) and works well with other JavaScript libraries like jQuery.

Simple syntax

ConstraintJS's API is very learnable and includes features for dynamic handlebars-like templates.

Examples: Live Handlebars Templates

ConstraintJS includes a Handlebars-like templating syntax. Unlike Handlebars templates, these templates are live—DOM nodes are created, moved, and removed dynamically without modifying other page elements. See the API documentation for more details.

Code (Templated HTML & JavaScript) Output

cjs.createTemplate(ex1_code, {libName: cjs}); // use template above

// works with jQuery ($)
cjs.createTemplate($("#ex2code"), {}, $("#ex2"));

Example: Dynamic JavaScript

ConstraintJS can also enhance lower-level JavaScript by making it easier to create developer-specified bindings between constraint variables and DOM elements. ConstraintJS gives developers a low-level API to create behaviors of any complexity.

Code (JavaScript) Output

var eradius_slider = sliderTemplate({max: 90, min: 10, val: 50}),
	eye_radius     = cjs(eradius_slider).toInt(),
	pradius_slider = sliderTemplate({max: 90, min: 10, val: 20}),
	pupil_radius   = cjs(pradius_slider).min(eye_radius),

	mouse_x = cjs(0),
	mouse_y = cjs(0);

var eyes = (['left', 'right']).map(function(float) {
	var eye   = eyeTemplate({fill: "white", size: eye_radius.mul(2), float: float}),
		pupil = eyeTemplate({fill: "black", size: pupil_radius.mul(2), float: ""}),

		eye_pos = cjs(function() { return $(eye).position(); }),
		dx = eye_pos.prop("left").add(eye_radius).sub(mouse_x),
		dy = eye_pos.prop("top").add(eye_radius).sub(mouse_y),
		d  = dx.pow(2).add(dy.pow(2)).sqrt().min(eye_radius.sub(pupil_radius)),
		angle    = dy.atan2(dx),
		eye_left = eye_radius.sub(pupil_radius, d.mul(angle.cos())),
		eye_top  = eye_radius.sub(pupil_radius, d.mul(angle.sin()));

	cjs.bindCSS(pupil, {
			position: "relative",
			left: eye_left.add("px"),
			top: eye_top.add("px")

	$(window).on("scroll resize mouseup", function(event) { eye_pos.invalidate(); });

	return eye;

$(window).on("mousemove", function(event) {
	mouse_x.set(event.pageX); mouse_y.set(event.pageY);