# WebCola hands back coordinates and leaves the drawing to you

> WebCola is a small TypeScript library that solves layout constraints and returns coordinates, leaving every pixel to the renderer you already have. Its packaging has drifted from its own documentation, which is the part worth checking before you adopt it.

**tgdwyer/WebCola** — Javascript constraint-based graph layout

- Repository: https://github.com/tgdwyer/WebCola
- Website: http://marvl.infotech.monash.edu/webcola/
- Stars: 2,099 · Forks: 260
- Language: TypeScript
- License: MIT
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/tgdwyer-webcola

## Constraint solving for graphs that come with rules

WebCola is a layout engine rather than a drawing library, and that boundary decides what you can build with it. The project's one-line description calls it a constraint-based graph layout in TypeScript, and the keywords declared in package.json run Graph, Layout, Constraints, Optimization. You hand it nodes and links, attach rules where the arrangement is not free, and it gives back coordinates. Two demos linked at the top of the README cover exactly two of those rule families: a small world graph carrying simple groups, and a separate page demonstrating alignment constraints. Teams that hand-place nodes in a diagram, or that pick a general charting library and then nudge positions by eye until nothing overlaps, are the ones with a real case for this package.

## Coordinates come out, rendering stays with your library

Whatever leaves the solver is a position rather than a picture, which pushes drawing, hit testing and interaction into your own code. The README's summary line says the library is for graph visualization and exploration using D3.js and other web-based graphics libraries, so the output is not bound to one renderer. That claim shows up in the repository layout too: the top-level entries are the src, `test`, `tasks` and `website` directories plus `cypress.json` and the rollup and TypeScript config files, with no separate drawing package to import. Nothing in that file list promises a component you can drop into a page and consider finished. It is a deliberate trade, and the effect is to move the work you keep rather than remove it.

## Three install paths, one of them typed through tsd

The browser route is two script tags pointing at the hosted copies, one minified and one full, and a page that already loads D3 needs nothing else:

```html
<script src="https://ialab.it.monash.edu/webcola/cola.min.js"></script>
<script src="https://ialab.it.monash.edu/webcola/cola.js"></script>
```

Use one or the other, since loading both defines the same globals twice. The minified file is also reachable from jsDelivr, and package managers cover the remaining routes. For a bundled project the npm install is a single line:

```bash
npm install webcola --save
```

Adding the entry to package.json before installing works the same way:

```json
"dependencies": {
  "webcola": "latest"
}
```

A Bower route is documented too:

```bash
bower install webcola --save
```

TypeScript users get pointed at tsd 0.6 from DefinitelyTyped and told to run `tsd link`, which is an unusual route given that package.json resolves types from a file inside the published package.

## The README build recipe predates the tsdx scripts

Here a close reading pays off. The build section still presents node, a plain install, a build and a test as the whole workflow, and it states that the build creates `cola.js` and `cola.min.js` in the dist directory:

```bash
npm install
npm run build
npm run test
```

package.json describes something else. Its build script is `tsdx build --name cola --format esm,umd`, a postbuild step runs the typings script, and that typings script executes `tsc -p tsconfig.dts.json` followed by `rollup -c rollup.dts.config.js`. No step in that chain emits a file called cola.js. The names the README promises and the names the package points at are two different sets, and anyone who follows the prose while watching the dist directory will conclude the build failed.

## Entry points that disagree with the documented output files

Four fields in package.json decide what your code actually loads:

```json
"main": "dist/cola.umd.development.js",
"module": "dist/cola.esm.js",
"unpkg": "dist/cola.umd.production.min.js",
"jsdelivr": "dist/cola.umd.production.min.js"
```

`main` resolves to the development build, so a CommonJS consumer pulls the unminified bundle with no minification step of its own. Bundlers that prefer `module` get the ESM file, and a plain script tag through unpkg or jsDelivr gets the minified one. Types come from `dist/cola.d.ts`, and the files array ships only the `dist` and `src` directories, so the source travels with the package. The consequence is easy to miss: which build you ship depends on which field your tool honours, not on anything the README explains.

## A test command configured to pass with no tests

The unit command behind `npm run test` is `tsdx test --passWithNoTests`, and the watch and coverage variants carry the same flag. Read literally, that flag lets the run exit green when no test file is found, so a clean result on a fresh clone tells you little about correctness. Verification effort sits elsewhere in the repository: there is a `cypress.json`, a `cypress` directory at the top level, and scripts named `cy:run`, `cy:open` and `cy:junit`, the last of which writes a mochaFile report. There is also a `tsconfig.example.json` driven by `compile-examples`, which means the example pages are type checked as their own project.

## A D3 v3 style interface over a two-version adaptor

One sentence in the README sets the integration cost: while the D3 adaptor supports both D3 v3 and D3 v4, the interface is styled like D3 v3, and the setup details live on the homepage rather than in the repository. D3 version 4 rewrote selection handling, so application code written against the newer style will not read the way the calls in this package expect. The devDependencies list `@types/d3` at `^4.5.0`, the typing line for D3 4 rather than anything newer, and the adapter is there to smooth over the difference rather than to erase it. Treat it as a compatibility layer and plan a small amount of glue when the rest of your page has moved on.

## Where this layout engine stops and your code starts

The operational answers are thinner than the API description. The project homepage is http://marvl.infotech.monash.edu/webcola/, while every script tag and the homepage link in the README point at a different host, ialab.it.monash.edu. The jsDelivr address adds another wrinkle: its path names a ref, WebCola, that is neither the default branch master nor a numbered build, so a page loading that file can receive something other than what npm installs. There is no rollback procedure, no dated history of solver changes and no migration note between the older cola.js layout and the packaged one, leaving a team that upgrades to compare output coordinates by hand. The last push was on 2026-04-30 and the newest numbered build is v3.3.8 from 2018-03-19, while the version field in package.json already reads 3.4.0. The MIT licence lets you embed the layout code inside a product you never open source, which is the one adoption question that carries no follow-up work.

## Conclusion

Adopt WebCola when the graph carries rules a general drawing library will not express, groups or alignment between nodes that must not drift, and when you already own the rendering layer. Do not adopt it expecting a ready-made viewer or build files named the way its README claims. Before committing, install it from npm, check which entry point your bundler resolves, and compare the returned coordinates against your current D3 version. And do not trust a green unit run, because that command passes when it finds nothing.

## FAQ

### Does WebCola draw the graph, or only compute the layout?

It computes the layout only. The project describes itself as a constraint-based graph layout for visualization and exploration using D3.js and other web-based graphics libraries, so drawing, hit testing and interaction stay in your code.

### How do I install WebCola and get TypeScript types?

`npm install webcola --save` covers a bundled project, and adding `"webcola": "latest"` to the dependencies block of package.json before running `npm install` does the same job. For complete definitions the README points at tsd 0.6 and the `tsd link` command, while package.json resolves types from `dist/cola.d.ts` on its own.

### Which D3 version does WebCola target?

The adaptor supports both D3 v3 and D3 v4, but the interface is styled like D3 v3. The README sends readers to the homepage for setup details instead of spelling out the adaptor calls in the repository.

### How do I build WebCola from source and view its examples?

Run `npm install` in the WebCola directory, then `npm run build` and `npm run test`. For the examples the README asks for a global `http-server` install, then `npm run website` and `http-server website`, which serves the pages on http://localhost:8080.

### Does the test suite prove WebCola works?

Not by itself: `npm run test` maps to `tsdx test --passWithNoTests`, which exits green when no tests are found. End-to-end checks run through Cypress with `cy:run` or `cy:open`, and the junit reporter writes a mochaFile report.

## Sources

- [License: MIT](https://github.com/tgdwyer/WebCola/blob/master/LICENSE)
- [Project website](http://marvl.infotech.monash.edu/webcola/)
- [README](https://github.com/tgdwyer/WebCola/blob/master/README.md)
- [Releases](https://github.com/tgdwyer/WebCola/releases)
- [tgdwyer/WebCola on GitHub](https://github.com/tgdwyer/WebCola)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tgdwyer-webcola
