Extend Sylus with a Nib

Today I am releasing Nib, an extensions library for Stylus, inspired by the SASS compass library. Nib is a very new library with a minimal feature set at the moment, however I need to get some of my semi-finished projects open-sourced to make way for bigger badder things, and I’m already finding this project quite useful so feedback and contributions are always welcome.

If you dont like to read, feel free to check out the short screencast.

Vendor Support

Nib currently supplies some cross-browser vendor support for properties, however this will surely expand and be refined as we go.

Enjoy The Little Things

Ever forget if nowrap is no-wrap, or whitespace over white-space? well I do, thanks to simple definitions like the following, these are completely interchangeable:

no-wrap = unquote('nowrap')

Augmented Border Radius

Border radius works as you might expected, however it is also augmented to support positioning. For example to round only the top of a box, use top 5px, or perhaps round the top and bottom differently with top 5px, buttom 10px. For example:

button {
  border-radius: top left 5px, bottom right 10px;
}

yields:

button {
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px;
  border-top-left-radius: 5px;
  -moz-border-radius-bottomright: 10px;
  -webkit-border-bottom-right-radius: 10px;
  border-bottom-right-radius: 10px;
}

Position Properties

Nib has three position mixins or “custom properties”, fixed, absolute, and relative. These shorthands are helpful since you can define three properties in one concise, legible manner.

fixed: top left
fixed: top 5px left
fixed: top left 5px
absolute: top 5px left 5px
relative: left -5px

Expanding to:

position: fixed;
top: 0;
left: 0;

etc.

Gradients

Nib makes working with gradients easier than you could imagine. The following call to linear-gradient() duplicates the property to which it is assigned to (not bound only to “background”), and generates the appropriate webkit and mozilla output:

body
  background: linear-gradient(right bottom, white, 80% black)

yields:

body {
  background: -webkit-gradient(linear, right bottom, left top, color-stop(0, #fff), color-stop(0.8, #000));
  background: -moz-linear-gradient(right bottom, #fff 0%, #000 80%);
  background: linear-gradient(right bottom, #fff 0%, #000 80%);
}

You may pass as many color stops as you like, optionally providing a position before or after the color for each, whichever you prefer.

Gradient Image Generation

Another powerful feature of Nib, is the ability to utilize node-canvas when installed, and auto-generate a data URI representation of the gradient for further browser support. The image below displays google chrome’s render on the left, and node-canvas on the right.

gradients

The linear-gradient-image() function generates the data uri only:

body
  background: linear-gradient-image(50px top, white, black);

Alternatively we can pass the size to a regular call to linear-gradient() and the data uri will be created along with the other properties:

body
  background: linear-gradient(50px top, white, black);

Components

Nib currently ships with 5 or 6 sets of buttons, however I welcome the addition of other flexible components, and of course more buttons :). Below is an example of utilizing the “bold” button, assigning a glow which adjusts appropriately within the mixin.

.bold
  bold-button()

.bold-alternate
  bold-button(glow: #00ABFA)

glow button

Jade Screencast - Template Engine For NodeJS

Introduction

This screencast covers an introduction to the Jade Template Engine for Node. Jade is an indentation based template engine inspired by Haml, with added support for the popular Express web development framework.

Iteration, Conditionals, and Debugging

Learn how to iterate objects and arrays, template conditionals, the debug option and how Jade’s error reporting works in this screencast.

nDistro - Node distribution toolkit

nDistro is a small bash project that allows you to define, and install node distributions within seconds. This means no GIT dependency, no compiling node from source with Make, no need to install node then install npm (node’s package manager).

nDistro distributions are easy to create, share, and install. Before we get into the details lets install nDistro:

$ cd /usr/local/bin && curl http://github.com/visionmedia/ndistro/raw/master/install | sh

Creating a Node Distribution

Pre-installed distributions take the shape of a single dotfile named .ndistro, which is actually a bash script loaded by ndistro. Here is an example of one of mine:

    node 0.1.102
    module senchalabs connect
    module visionmedia express 1.0.0beta2
    module visionmedia connect-form
    module visionmedia connect-redis
    module fictorial redis-node-client
    module visionmedia jade
    module visionmedia ejs

We specify the pre-compiled node binary version, as well as several modules defined by:

 module <username> <project> [version]

Currently the node binaries are fetched from my “nodes” repo, so feel free to contribute some nodes :D

Installing a Distribution

Installing a distro is even easier! In the directory containing .ndistro execute:

$ ndistro

You should see the following stdout (or similar):

$ ndistro

... installing connect
... installing express
... installing connect-form
... installing connect-redis
... installing redis-node-client
... installing jade
... installing ejs
... installing node 0.1.102
... installation complete

BAM!! you now have bin/node, and bin/express to get started creating some cool web apps. Try it out:

$ ./bin/node

node> require('express')
{ version: '1.0.0beta2'
, Server: { [Function] super_: { [Function] super_: [Object] } }
, createServer: [Function]
}

Updating A Distribution

Updating is easy too, want to re-install a module?:

$ rm -fr modules/connect-redis

and then run nDistro again:

$ ndistro

You should see something like:

... already installed connect
... already installed express
... already installed connect-form
... installing connect-redis
################################################ 100.0%
... already installed jade
... already installed ejs
... already installed redis-node-client
... already installed node-formidable
... already created application
... already installed node
... installation complete

Future Ideas

  • Utilize Gists (or create a quick site) to share distro recipes.
  • Utilize wget / curl depending on which is available
  • Expand the API, perhaps allow app skeletons

Express 1.0beta

Yesterday I released Express 1.0.0beta, a Sinatra inspired Node web development framework.

The beta is a near re-write consisting of roughly 300 commits, introducing new features, removing legacy code, and improving documentation. Express now runs on the Connect middleware framework, which replaces the previous concept of a Plugin. The performance of express has also been optimized and can now respond much faster than previous versions.

Connect

By abstracting the Express Plugin’s to a specific middleware framework, the community can now build on, and utilize this functionality to power their own frameworks. Connect currently provides:

  • bodyDecoder Buffers and parses json and urlencoded request bodies (extenable)
  • conditionalGet Provides 304
  • errorHandler Handles exceptions thrown, or passed through the stack
  • debug Outputs debugging console to all html responses
  • format Handles url path extensions or
  • gzip Compresses response bodies with gzip executable
  • lint Aids in middleware development
  • logger Provides common logger support, and custom log formats
  • methodOverride Provides faux HTTP method support via the _method param
  • responseTime Responds with the X-Response-Time header in milliseconds
  • compiler Supports arbitrary static compilation of files, currently supports less and sass.
  • cacheManifest Provides cache manifest for offline apps
  • jsonrpc Provides JSON-RPC 2.0 support
  • staticProvider Serves static files
  • cookieDecoder Provides cookie parsing support
  • session Provides session support
  • cache Provides memory caching
  • pubsub Publish subscribe messaging support
  • repl Read Evaluate Print Loop attached to
  • vhost Virtual host support

Performance Enhancements

Express is now much faster, with a concurrency of 80, and 8000 it can easily serve the typical “Hello World” response with ~10,000 requests per second on my machine. Ruby’s Thin (1.2.7) by comparison serves ~6500 rps. Finally by adding Sinatra in the mix I get ~1900 rps.

These numbers are to be taken lightly of course, and are simply relative, to re-cap:

Express        ~10,000
Rack/Thin      ~6,500
Rack/Sinatra   ~1,900

Graph for fun:

express vs sinatra

Documentation Overhaul

The new docs include a 1.x Migration Guide which should cover most of the changes that would be required to get you up and running. Another thing worth mentioning is that the docs are now generated via Markdown, and are located within ./docs which provides an easy way for developers to contribute docs.

I also have a Contrib Guide for those who are interested in helping Express out, and of course a completely revamped developers Guide.

For those who like to dig in deep and check out internals, my dox project generates the annotated source for Express.

Application Generating Executable

Express now ships with the express executable, creating app skeletons with a single tiny command:

$ express

thats it! of course view —help for more information.

Future of Express

From now on Express is clutter-free, no more dependencies on random extension libraries, no more high level http client library, just simply performance, routing, responding, configuration, and views. Feel free to post an issue if you find a bug, or have suggestions for focused features that you would like to see in the framework.

Looking forward to 1.0, Happy Express-ing everyone :)

Node JavaScript Test Coverage

Today I released Expresso 0.4.0, a TDD framework for node which uses my node-jscoverage project to instrument your library, providing optional test coverage reporting when the —cov flag is used.

Expresso

If you dont know anything about expresso, it executes tests in parallel, so even ~1000 assertions against live http servers can execute in less than a second. By doing so we unfortunately suffer slightly in terms of reporting, although expresso is entirely CI friendly, and reports both sync, async, and uncaught exceptions in a clean manor.

Coverage Reporting

Below is a test coverage example, currently I report the following:

  • LOC: lines of code
  • SLOC: source lines of code (aka no comments etc)
  • source reports, showing the line numbers as well as coverage hits

javascript test coverage

More Information

Into writing tests for your node JavaScript? prefer insanely fast execution of async TDD? check out expresso! now! do it! before I go drink