Bikeshed: the pre-processor behind a lot of the web's specifications
:bike: A preprocessor for anyone writing specifications that converts source files into actual specs.
At a glance
- What is it?
- Bikeshed turns a source file that contains only the spec text and some shorthands into a finished specification with boilerplate, bibliography and indexes filled in. It is used for CSS, for other W3C working groups, for WHATWG and for the C++ standards committee, and it is released into the public domain under CC0.
- Who is it for?
- Bikeshed fits a team writing a specification that has to look like a specification, with cross-references that resolve, an index that stays current and a bibliography that is generated rather than maintained, and it costs nothing to adopt because it is public domain.
- Can I use it commercially?
- Yes. CC0-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A source document in, a finished specification out
Bikeshed is a pre-processor for spec documents, and the transformation it performs is the whole point.
It takes a source document containing only the actual spec content, plus several shorthands for linking to terms and other things, and turns it into a final spec document with the appropriate boilerplate, bibliography and indexes all filled in.
That division is what makes it usable at scale. A specification is mostly structure: the status section, the abstract, the table of contents, the index of terms, the list of references, the conformance section, the acknowledgements. None of that is content, all of it has to be consistent with the content, and all of it is mechanical. Writing it by hand means that every structural change is an edit in a dozen places, and the index in particular cannot be maintained by hand for a long document. So the content goes in a file, and the structure is generated from it.
The adopters are the proof that the approach scales. Bikeshed is used on specs for CSS and many other W3C working groups, on WHATWG, on the C++ standards committee's work, and elsewhere. The CSS specifications are among the most demanding documents anyone publishes, with hundreds of definitions that have to be cross-linked consistently, and the fact that a single tool handles them is a good argument for how well the model works.
The tool is released into the public domain. The licence is CC0, which means the document and all associated files in the GitHub project can be reused, remixed or otherwise appropriated for your own use without restriction. The README makes the point in a sentence that says more about the intent than a licence file does: don't ask for permission to use any part of the project, just use it, and attribution is appreciated but not required.
The primary language of the repository is listed as HTML, which is a fair description of a tool whose output is HTML and whose input is mostly HTML with extra syntax.
Autolinking is the feature that makes the source readable
The first feature on the list is automatic linking of terms to their definitions based on text, and it is the one that changes how a document reads.
You write `Use <a>some term</a> to...` and Bikeshed links it automatically to the `<dfn>some term</dfn>` elsewhere in the document, or in another spec entirely. The cross-document case is the remarkable one, because a term defined in the HTML specification can be linked from a document that has never seen that definition, which means the reference stays correct when the definition moves.
The mechanism is why the source stays readable. In a hand-written specification, a cross reference is an anchor with a generated id, and the author has to keep the id and the anchor in step. With autolinking, the author writes the term and the tool finds the definition, generates the ids and produces the link. That is what turns a document that is a pile of cross-references into a document where the cross-references are invisible.
The second feature follows from it. Automatic id generation for headings and definitions, based on their text, means the ids in the output are derived from the words rather than being invented, and the id in a link is derived from the same words, so they cannot drift apart. The third is the shorthand syntax that makes the links short enough to be worth writing by hand: `[[FOO]]` for a bibliography entry, `<<foo>>` for a grammar production, `'foo'` for a CSS property name and `{{foo}}` for an IDL term.
So the source of a Bikeshed document is not a different language. It is HTML with a set of conventions, and the conventions are chosen so that the parts a human touches often, the links, are the parts that are cheapest to write.
Markdown, IDL and railroad diagrams
The remaining features are about making a specification document comfortable to write, and they fall into two groups.
The first group is about the prose. There is Bikeshed-flavored Markdown, a slight variant that is extra-friendly to intermixing with normal HTML, and the README notes that besides the few intentional divergences, compliance with CommonMark is expected. There is a compact syntax for writing property-definition tables, which in a CSS specification is the single most repetitive structure there is, and a mechanism for automatic whitespace-prefix stripping from `<pre>` contents, so the contents can be indented properly in the HTML source without the indentation ending up in the output.
The second group is about the machine-readable parts of a specification. There is automatic IDL processing and syntax checking for `<pre class=idl>` contents, so an author does not have to mark up every significant term themselves, and the tool both highlights the identifiers and tells you when the interface definition does not parse. And there is automatic generation of railroad diagrams from `<pre class='railroad'>` contents, which is how a grammar gets a picture.
None of that is exotic, and all of it is the reason a spec author does not have to hand-build a diagram or a syntax-coloured interface listing. The whole feature list is a list of things that would otherwise be a script somebody wrote for their own document, which is the best possible characterisation of a spec pre-processor: it collects the conventions that every working group needs and makes them the default.
The documentation is generated by Bikeshed itself, which is a nice touch and also a test of the tool, and the whole documentation is available at `speced.github.io/bikeshed`.
Fatal errors that the tool recovers from anyway
There is a section in the README about fatal errors, and it is a design statement rather than a warning.
Bikeshed generates fatal errors for lots of things that it wants you to fix, but generally recovers gracefully from them anyway. The tool wants to be strict about correctness and pragmatic about output, and the escape hatch is a flag:
bikeshed -f specThe README explains the use case. If you are getting a fatal error, do not have time to fix it, and just need a spec right now, you can force Bikeshed to generate anyway. It is also sometimes useful when converting a spec to Bikeshed for the first time, so that you can see all the errors at once and fix them in whatever order is easiest, rather than having to deal with them one by one with no idea when they will end. In that case you may also want to silence the warnings to reduce the visual noise until you have it at least building successfully, with `bikeshed -qf spec`.
So there are two switches with two different jobs. The `-f` forces the output, and the `-q` quiets the output, and the combination is the just build it mode.
For a converter coming from a hand-written HTML specification, that mode is the right entry point, because the error list from a conversion is long and the order in which the errors are fixed does not matter, and a tool that stops at the first one turns a two hour job into a two day job.
Files, packaging and a test rig that runs in Docker
The conventions of the project are small and strict, and they start with the file extension.
The preferred file extension for source files is `bs`, like `index.bs`. Bikeshed automatically recognises `*.bs` files in the folder it is run in, and assumes that you want an output file of the same name with an `.html` extension. The repository also contains a syntax highlighting script for Bikeshed source files, and there is one for the TextMate format in `Bikeshed.tmLanguage` and an `emacs/` directory for the other editor.
The legacy extension is still recognised. Bikeshed also recognises files with `*.src.html` for backwards compatibility with older CSS specs, although most such specs have since switched to `.bs`. The README is blunt about why that is a problem: using `.src.html` in most text editors will display the file with HTML source formatting, which is not generally what you want.
The packaging is a classic setup.py with a twist. The version is read from `bikeshed/semver.txt` rather than being written in the file, the install requirements are parsed out of `requirements.txt` with a small comprehension, and the project requires Python 3.12 or later. The console entry point is `bikeshed = bikeshed:main`, and the package ships a `py.typed` marker.
The runtime requirements are pinned exactly, which is what a tool that others depend on for their build should do:
about-time==4.2.1
aiofiles==25.1.0
aiohttp==3.13.5
cddlparser==0.6.0
html5lib==1.1
kdl-py==1.2.0
lxml==6.1.0
pillow==12.2.0
pygments==2.20.0
requests==2.33.1
tenacity==9.1.4
widlparser==1.5.0The test rig is a Playwright suite that runs inside the official container image, and the comment in the package metadata explains the constraint precisely: the version of the Docker Playwright image must exactly match the versions of `@playwright/test` in the dev dependencies and in the GitHub Actions configuration, and the Playwright version in the dev dependencies should not carry the caret prefix so that it does not auto-upgrade and get out of sync.
That is a small piece of engineering hygiene, and it is the kind of thing that only matters once a project has a snapshot test that depends on a browser build.
Where Bikeshed is the wrong tool
The limits are clear enough to state in a sentence: Bikeshed is a spec pre-processor, and using it for anything else buys you a pile of spec conventions you do not need.
The first limit is the domain. A team writing documentation, a manual, a book or a set of API pages does not need cross-spec autolinking, an index of defined terms, railroad diagrams generated from grammar blocks, or the fatal error list that Bikeshed generates for a document that is not a specification. Those features are the value in a spec and noise anywhere else.
The second is the file format. The `.bs` extension and the Bikeshed flavour of Markdown are Bikeshed's own, and the README is careful to say that the flavour is a slight variant of CommonMark with a few intentional divergences. So a project that adopts Bikeshed has source files that other tools, and other people, will not read natively, and an editor without the highlighting script will show them as plain text.
The third is the dependency and the Python version. The package requires Python 3.12 or later, and it pulls in aiohttp, lxml, html5lib, pillow, requests and a handful of parsers for the specific formats a specification uses, including IDL and KDL and CDDL. That is a reasonable set for what it does, and a heavy one for a small tool.
The alternative for a documentation project is to keep the source in a form that a general toolchain understands, Markdown or AsciiDoc, and to generate an index with a general tool. The difference in approach is that Bikeshed is a domain tool with a domain format, and a general tool is a general tool, and the question is whether your document is a specification. If it is, the domain tool wins by a distance, because the conventions it enforces are the conventions a specification has to follow anyway.
Editorial conclusion
Bikeshed fits a team writing a specification that has to look like a specification, with cross-references that resolve, an index that stays current and a bibliography that is generated rather than maintained, and it costs nothing to adopt because it is public domain. It is the wrong tool for documentation, since the value is in the spec conventions rather than in the processing, and it is the wrong choice for a team that wants a general documentation toolchain with a stable file format. Before using it, read the fatal error section, because the tool reports a great deal and recovers from most of it, and decide deliberately whether your project wants the `.bs` extension and the Bikeshed flavour of Markdown, since both are things other tools will not understand.
Frequently asked questions
What is Bikeshed?
It is a pre-processor for spec documents that turns a source file containing only the spec content and some shorthands into a final document with the boilerplate, bibliography and indexes filled in. It is used on CSS and other W3C working group specs, on WHATWG, on the C++ standards committee's work, and elsewhere.
How do I run Bikeshed?
It can be installed and run locally, requiring no network access unless you are updating, or accessed online through the W3C spec-generator. The console entry point is `bikeshed`, and the convention is a source file such as index.bs with an .html output of the same name.
What does the -f flag do in Bikeshed?
It forces generation despite the fatal errors Bikeshed reports, which it generally recovers from anyway. The `-q` flag silences the warnings as well, which the README suggests when converting an existing spec, so that you can see all the errors at once and fix them in whatever order is easiest.
What licence is Bikeshed under?
CC0. The README states that the document and all associated files in the project can be reused, remixed or otherwise appropriated without restriction, and asks that permission is not sought for any part of the project, with attribution appreciated but not required.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/speced-bikeshed)Was this useful?