npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

cwrap

v0.1.0

Published

Generate NodeJS bindings for modules that have a C interface

Downloads

7

Readme

CWrap

CWrap is a NodeJS utility I've created to help me create (NodeJS) wrappers for library modules that have a C interface.

At its core, CWrap is little more than a template engine with a passing resemblence to [Mustache] 1. The rest of the work is more or less left to the programmer, though the module provides a function that extracts the interface description from an XML file generated by [SWIG] 2.

Prerequisites

  • Make sure you have installed and read about [node-gyp] 3, the awesome tool that makes it easy and straightforward to create native extensions for NodeJS.
  • If you haven't already, get acquainted with how to actually write NodeJS bindings. A good place to start is [this slideshow] 4; you may also have to have a look at the [V8 Embedder's Guide] 5.
  • Install [SWIG] 2, and put the executable in your path.

Overview

The process to create NodeJS bindings for your C module is easily summarized:

  • call SWIG on your header file to generate an XML description of the interface
  • use CWrap's parseSwigXML() function to extract a JSON interface description from the XML
  • apply a code template on the interface description to obtain the wrapper code

Getting started

Unfortunately, the sample provided at the time of writing cannot actually be used (it will fail at the linker stage), as it generates bindings for a module that is not free software (for lack of time, I just used what I had already done). However, the sample should still be sufficient to point you in the right direction.

It is probably best to start with the sample template nodebindings.tmpl.cc - perhaps glancing at the generated source lsdisplay2_wrap.cc from time to time will help you not to get lost in all those template markers.

Let's get the template syntax out of the way - it's really simple:

  • Tags are introduced with the characters {{$ and closed with }}.
  • The foreach (or its alias forall) tag will iterate over the elements of an array or object; the block it controls must be closed with a end tag.
  • The if, elsif, else and end tags will work together just as you'd expect them to. There is no need for parentheses after if or elsif; otherwise, the syntax is JavaScript, though array indices are not supported (yet?)
  • The = tag inserts a value into the code. It's an inline tag and does not need or support a closing end.
  • Tags starting with a dash - are considered comments. No closing tag.
  • The macro tag defines a named "subroutine"
  • The call tag executes a macro
  • The list tag (inline, no closing tag) is used to fill out the parameter list of a function call.

Next should come the genwrapper.js code, which is the code you would actually run in order to obtain the wrapper code. What it does it read the XML generated by SWIG, extract from that the basic interface description, then run a custom function called postProcess() that sifts through the interface description and does things like converting functions to methods, convert output parameters to return values, etc. The resulting, updated interface description is the JSON object that will be "fed" to the template engine.

What must be understood here is that the nodebindings.tmpl.cc template and the genwrapper.js processor are made for each other and are both custom. Both parts will have to be adapted to the module you are wrapping. It's completely up to you how much, if any, of these sample files you want to keep, what to replace and what to just toss out. They both are just samples.

Final words

It is understood that CWrap could be improved upon in major ways, starting by making it more modular. At the end of the day though, it can never be a fire-and-forget tool - a header file, by itself, is simply not enough information, as a general rule, to generate full, production-quality bindings from.

I would welcome feedback on this tool. The need for something like this (well, actually for something better than this, but I had to start somewhere :-) ) seems very real, and I would enjoy discussing this.

2013-03-29 Jean-Pierre Gygax, practicomp.ch