IPFS specs are a set of documents with a status badge, and none of them is stable yet
Technical specifications for the IPFS protocol stack
At a glance
- What is it?
- The ipfs/specs repository holds the technical specifications for the IPFS protocol stack, and its most useful device is a six-level badge system that says in one word how far along each document is. The README is blunt that nothing in the repository is permanent or even stable, and most subsystems are still drafts or reliable, which tells implementers exactly how much weight to put on them.
- Who is it for?
- The IPFS specs repository fits an implementer who needs to know which parts of the protocol are settled and which are still moving, and a contributor who wants to change a document through a reviewable process rather than a pull request that rewrites the rules. It does not fit a reader looking for a frozen reference, because the README states that no spec in the repository is stable or permanent yet.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 29 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 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The README tells you not to read the specs here
The first line of the README is an instruction, and it is a useful one. Don't read the specs here, go to specs.ipfs.tech, it's a much better experience. The homepage of the project is the same site, and the repository is the source that the site is generated from.
That arrangement is not vanity. The specifications in this repository are long markdown documents, and a protocol reference is read by search, by link and by scrolling through a rendered page. A reader who lands in a GitHub file view gets the text without the navigation, the cross-references or the sidebar that makes a multi-document specification usable.
The repository description is a technical specifications for the IPFS protocol stack, and the primary language is recorded as HTML, which tells you that the site is the deliverable and the markdown files are the input. The top-level entries show the structure clearly. There is a directory per subsystem, with ipns/ and routing/ and http-gateways/ as directories and a set of standalone documents: ARCHITECTURE.md, BITSWAP.md, DWEB_ADDRESSING.md, IMPORTERS_EXPORTERS.md, IPNS.md, KEYCHAIN.md, KEYSTORE.md, MERKLE_DAG.md, REPO.md, REPO_FS.md, SECURITY.md and UNIXFS.md.
That list is the protocol in miniature. A Merkle DAG, a Unix-like filesystem on top of it, a repository and its import and export machinery, an addressing scheme for the distributed web, naming that survives a content change, key management, and the exchange protocol for fetching blocks. Anyone implementing any part of IPFS is working from these files.
The user support material is elsewhere by design. The README points to docs.ipfs.io for documentation, discuss.ipfs.io for discussion forums and a community resources page, so the specification repository is kept for the specification.
Six badges, and an admission that none of them reads stable
The most valuable thing in the README is the badge legend, because it turns a vague question into a lookup. We use the following label system to identify the state of each spec.
The ladder runs from wip, a work-in-progress, possibly to describe an idea before actually committing to a full draft of the spec. Then draft, which is a draft that is ready to review and should be implementable. Then reliable, a spec that has been adopted, implemented, and can be used as a reference point to learn how the system works. Then stable, which the project considers close to final, where it might be improved but the system it specifies should not change fundamentally. Then permanent, which will not change. And finally deprecated, which is no longer in use.
Each level is a promise about how much freedom an implementer has, and the ordering is careful. Draft means you can build against it, but it may still move. Reliable means it has been built. Stable means the shape will not change even if the wording improves. Permanent means do not plan around it changing, and deprecated means stop.
Then comes the sentence that matters most, and it is the reason to read the README rather than skim it. Nothing in this spec repository is permanent or even stable yet. Most of the subsystems are still a draft or in a reliable state.
For an implementer, that is a genuinely useful piece of information and it is unusual to see it stated plainly. A protocol specification that is being actively rewritten underneath you is a real risk, and here it is labelled rather than implied. It also sets expectations for the ecosystem: the specifications are moving, implementations track them, and the badge on a document tells you how far behind you might be.
IPIP is the change process, and it has a threshold
How a spec changes is as important as what it says, and the README describes the process by name. It works through the InterPlanetary Improvement Process, IPIP, with a page describing the process itself, a list of ratified IPIPs, and a list of open IPIPs which is implemented as a pull request search filtered on the ipip label.
Then there is the question the README anticipates from every contributor: how to decide between an issue and an IPIP.
What does not need an IPIP: the spec has a bug, something that is plainly a mistake, and adding more details, test vectors, and editorial or cosmetic changes. What needs an IPIP: an addition to the protocol that could cause interop issues.
That threshold is the interesting part, because it is about interoperability rather than about size. A typo, a missing example or a clarification does not change what any two implementations do when they meet, so it does not need a formal process. Anything that changes the behaviour of the protocol does, because a node running the old behaviour and a node running the new one have to keep working together. That is the same logic that makes any distributed protocol slow to change, and naming it is what lets a project move quickly on editorial work without moving slowly on everything.
The repository carries the machinery for this. There is an IPIP/ directory, an IPIP_PROCESS.md document describing the process, and an ipip-template.md that is the starting point for a proposal. A new protocol, or a change to an existing one, starts as a pull request against this repository carrying that template, and it either gets ratified or it does not.
The README also states the bar for participation. Suggestions, contributions and criticisms are welcome, but it asks that you familiarize yourself deeply with IPFS, the models it adopts, and the principles it follows. The repository falls under the IPFS Code of Conduct, and there is an AGENTS.md at the root for tooling that works with the repository.
The site is generated, and the build writes the security contact file
The build is small and it is the interesting part of the repository tooling. The package.json names the project ipfs-specs-website, keeps it private, and depends on a single package, spec-generator, with the version at 1.8.1 or above.
The Makefile has four targets and they are all about turning markdown into a site.
npx spec-generator -c .config.jsonThat is the generator invocation, and the .config.json at the repository root is what tells it what to generate. The website target first cleans the output directory, then runs install, which runs npm ci with a frozen lockfile when node_modules is missing or when package-lock.json has changed. After generating, the build touches out/.nojekyll, which stops the hosting from trying to run Jekyll over the output, and then runs a script to generate the security contact file.
That last step is a detail worth pausing on, because it is the kind of thing that only matters if you are running a domain. The script is scripts/gen-security-txt.mjs and it writes out/.well-known/security.txt, the standard location for a security.txt file, which tells researchers where to report a vulnerability and what the policy is.
There is also a watch target, which runs the same generator with a watch flag so the site rebuilds as you edit, and a superlinter target that runs the markdown linter in a container.
docker run --rm -e VALIDATE_ALL_CODEBASE=false -e RUN_LOCAL=true -e VALIDATE_MARKDOWN=true -e MARKDOWN_CONFIG_FILE=".markdownlint.json" -e LINTER_RULES_PATH="." -e DEFAULT_BRANCH='main' -v $(shell pwd):/tmp/lint ghcr.io/super-linter/super-linter:slim-v7The configuration comes from the .markdownlint.json file at the root, and the rules are applied to the repository rather than to a single directory. The whole build is therefore: markdown in, spec-generator, static site out, with a security contact file produced as a side effect of the build rather than maintained by hand.
There is no test suite, because the build is the test
The package.json test script is a stub, and it is worth looking at directly.
"test": "echo \"Error: no test specified\" && exit 1"That is the default npm placeholder, left in place. For a website repository that is arguably correct, since there is no code to unit test, but it does mean the npm test script tells you nothing.
What plays the role of a test here is the linter and the site build. The superlinter target runs markdown validation against the repository with the project rules, and the website target proves that every document in the tree can be rendered by spec-generator, which fails loudly if a document is malformed or a link is broken. For a repository whose content is prose that other people implement against, those two checks cover the failure modes that matter: a document that cannot render, and a document that violates the formatting rules.
The rest of the tooling is minimal and conventional. There is a .config.json for the generator, a package-lock.json and a .markdownlint.json, a .github/ directory for workflows, and a scripts/ directory holding the security.txt generator. There is also a SECURITY.md at the root, which is the policy document the generated security.txt points at, and an ARCHITECTURE.md that describes how the pieces of the stack fit together for a reader who arrives at one subsystem document without the wider context.
The absence of a test suite is a fair criticism in the abstract, but for this particular repository it would be testing the generator, not the specifications. The specifications are checked by the people who implement them, which is exactly what the badge system and the IPIP process are there to coordinate.
No licence and no releases, so a copy of a spec is not a dependency
Two facts about the repository as a software artefact are worth stating plainly, because they change how you should treat it.
The first is the licence. The repository metadata reports the licence as unknown, a custom licence that GitHub cannot classify, and there is no LICENSE file among the top-level entries. The README does not mention licensing at all. That is a gap rather than a decision: a specification is not normally the kind of artefact people redistribute, but the documents are text and the licence question is a real one for anyone embedding them.
The second is the release history. There are no GitHub releases, which is consistent with a repository whose output is a website rather than a package. There is no version of the protocol you can pin, no changelog of spec changes per version, and no artefact to depend on. What you consume is the current state of the documents, and the badge on each document.
Taken together, these point at the correct mental model. This repository is a working document, not a released dependency. If you want to know whether a protocol detail is settled, you read the document and look at its badge. If you want to know whether a change is in flight, you look at the open IPIPs. If you want to know whether the text is authoritative, you read it at specs.ipfs.tech, because the README tells you not to treat the repository as the reading experience.
The last push was on 2026-09-26 and the repository is not archived, so the documents are being edited continuously, which is consistent with a set of specifications where most subsystems are still a draft or in a reliable state and the whole set is moving together.
Editorial conclusion
The IPFS specs repository fits an implementer who needs to know which parts of the protocol are settled and which are still moving, and a contributor who wants to change a document through a reviewable process rather than a pull request that rewrites the rules. It does not fit a reader looking for a frozen reference, because the README states that no spec in the repository is stable or permanent yet. Before relying on a spec, read its badge and its dependency on other specs, follow the linked IPIP if one is open, and check the .well-known/security.txt that the build generates for the current security contact.
Frequently asked questions
Where should I read the IPFS specifications?
The README says not to read the specs in the repository, and to go to specs.ipfs.tech instead, which is where the site is generated from. For user support, the README points to docs.ipfs.io for documentation and discuss.ipfs.io for the discussion forums.
What do the status badges on the IPFS specs mean?
There are six states: wip for a work in progress, possibly only an idea, draft for something ready to review and implementable, reliable for a spec that has been adopted and implemented, stable for one considered close to final whose underlying system should not change fundamentally, permanent for one that will not change, and deprecated for one no longer in use.
Do I need an IPIP to change an IPFS spec?
Only for an addition to the protocol that could cause interop issues. A spec bug that is plainly a mistake, and adding more details, test vectors, or editorial changes, do not need an IPIP. IPIPs are tracked as pull requests labelled ipip, with the ratified and open lists published on the specs site.
How is the IPFS specs website built?
With the Makefile. The website target cleans the output directory, installs dependencies with npm ci and a frozen lockfile, runs npx spec-generator -c .config.json, touches out/.nojekyll so the hosting does not run Jekyll, and then runs scripts/gen-security-txt.mjs to produce the .well-known/security.txt file. A watch target runs the generator in watch mode.
Which parts of the IPFS protocol stack are covered by specs?
The repository holds documents including ARCHITECTURE.md, BITSWAP.md, DWEB_ADDRESSING.md, IMPORTERS_EXPORTERS.md, IPNS.md, KEYCHAIN.md, KEYSTORE.md, MERKLE_DAG.md, REPO.md, REPO_FS.md, SECURITY.md and UNIXFS.md, plus directories for ipns/, routing/ and http-gateways/ and the IPIP process material.
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/ipfs-specs)Was this useful?