Understanding IPFS in Depth(3/6): What is InterPlanetary Naming System(IPNS)? by@vasa

Understanding IPFS in Depth(3/6): What is InterPlanetary Naming System(IPNS)?

This is a continuation of the “Understanding IPFS in Depth” series. We will dive into the Naming System of IPFS, InterPlanetary Naming system(IPNS) We will explore how routing works in IPFS and how IPNS works? And at last, we will play with IPNS to host and set up routing of my website totally using IPFS stack. The IPNS is a global namespace based Public Key Infrastructure which allows us to build trust chains (so public peer) and is still compatible with other name services.
Vaibhav Saini HackerNoon profile picture

Vaibhav Saini

Entrepreneur | Co-founder @tbc_inc, an MIT CIC incubated startup | Speaker |https://vaibhavsaini.com

facebook social iconlinkedin social icongithub social icontwitter social icon

Why do need IPNS, How to Use it and it’s Comparison with DNS

This post is a continuation(part 3) in a new “Understanding IPFS in Depth” series which will help anybody to understand the underlying concepts of IPFS. If you want an overview of what is IPFS and how it works, then you should check out the first part too 😊 Understanding IPFS in Depth(1/6): A Beginner to Advanced Guide

In part 2, we discussed the Significance of IPLD(InterPlanetary Linked Data), How it Works and its technical specification. We also went through a tutorial in which we created a medium like publishing system, solely using IPLD. You can check it out here: Understanding IPFS in Depth(2/6): What is InterPlanetary Linked Data(IPLD)?

If you like high-tech Web3 concepts like IPFS, Libp2p, Multiformats, IPLD, etc., explained in simple words with interactive tutorials, then head here.

In this part, we will dive into the Naming System of IPFS, InterPlanetary Naming System(IPNS). We will explore:

  • What is the need for IPNS? How is it comparable to today’s DNS(Domain Name System) and how it differs from it?
  • We will explore how routing works in IPFS and how IPNS works?
  • And at last, we will play with IPNS. We will host and set up routing of my website totally using IPFS stack.

Hope you learn a lot about IPFS from this series. Let’s get started!


In order to understand why we need IPNS, let’s see how currently we access our photos, videos, and memes using IPFS.

BTW, if you want to follow along me, you can download my website like this:

wget --mirror --convert-links --adjust-extension --page-requisites 
--no-parent https://vaibhavsaini.com

When I add my website to IPFS, I get the following output:


(adding my website folder to IPFS)

Now, I can access my website at


But this link has a few problems:

  • Firstly, it’s hard to read, let alone remember.
  • Secondly, it’s an immutable link. What I mean by an immutable link is that this link is permanent(due to the nature of content-addressing). If I were to add even a comma anywhere in my website, the CID of the root folder will change, thus changing the link to my website. So, every time I change anything on my website, I have to give the new link to everyone who wants to access my latest website…Not cool.

Here is where IPNS comes in.

By using IPNS you can generate a mutable link, which:

  • will be human-readable and easy to remember.
  • points to the latest version of your website, profile photo, video etc.

A name in IPNS(the hash follows

in a link) is the hash of a public key. It is associated with a record containing information about the hash it links to that is signed by the corresponding private key. New records can be signed and published at any time.

So, in other words, IPNS is a global namespace based on Public Key Infrastructure (or PKI) which allows us to build trust chains (so you can follow a public key to its route peer), giving us encryption and authentication, and is still actually compatible with other name services. So for example, we can even map things like DNS entries, onion, or bit addresses, etc. to IPNS addresses.

IPNS is not the only way to create mutable addresses on IPFS. You can also use DNSLink (which is currently much faster than IPNS and also uses more readable names. We will learn more about it below). Other community members are exploring ways to use blockchains to store common name records. Here is a great comparison of different projects working on a naming system for the distributed web.

IPNS and DNS share a few similarities. Both solve similar issues in their respective systems, former in a content-addressed system and latter in a location-addressed system.

In a location-addressed system(today’s old school internet), we use IP:PORT combination to access our data. So, in a location-addressed system, my website’s address will be:

which is not also neither readable nor easy to remember.

But this always points to the latest content hosted on this address.

Using DNS, we associate this IP with a domain name, so you can access the website at vaibhavsaini.com.

Ok, But How it Works?

IPNS can be implemented in many ways, but its current implementation uses Distributed Hash Table (DHT). As a consequence, only the most recent mapping of each URI to its corresponding hash is available for resolution, forgetting any historical mappings. This is not good from the archival perspective as the previous versions of a file might still exist in the IPFS store, but their corresponding URI mappings are lost.

Let’s use

node module to understand how a IPNS record is published.

const ipns = require('ipns');
const crypto = require('libp2p-crypto'); //for generating RSA keypair

function generateRsaKeypair(){
    //generating an 2048 bit RSA keypair
    crypto.keys.generateKeyPair('RSA', 2048, async(err, keypair) => {
            console.log('error ', err);
            console.log("\nGenerated new RSA Keypair\n");

Creating an IPNS record with a lifetime

ipns.create(privateKey, value, sequenceNumber, lifetime, [callback])

privateKey (PrivKey RSA Instance): key to be used for cryptographic operations.
value (string): ipfs path of the object to be published.
sequenceNumber (Number): number representing the current version of the record.
lifetime (string): lifetime of the record (in milliseconds).
callback (function): operation result.
function createIpnsRecord(keypair){
    let sequenceNumber = 0;
    let lifetime = 1000000; //1000000 milliseconds
    let value = 'QmYVd8qstdXtTd1quwv4nJen6XprykxQRLo67Jy7WyiLMB'; //hash to my website
    var recordData;
    ipns.create(keypair, value, sequenceNumber, lifetime, (err, entryData) => {
            //Created new IPNS record
            console.log("\nGenerated new IPNS record\n");
            validateIpnsRecord(entryData, keypair);

Creating an IPNS record with a fixed expiration datetime.

ipns.createWithExpiration(rsa, value, sequenceNumber, expiration, [callback])

privateKey (PrivKey RSA Instance): key to be used for cryptographic operations.
value (string): ipfs path of the object to be published.
sequenceNumber (Number): number representing the current version of the record.
expiration (Date): Date object.
callback (function): operation result.

function createIpnsRecordWithExpiration(keypair){
    ipns.createWithExpiration(keypair, value, sequenceNumber, expiration, (err, entryData)=>{

Validate an IPNS record previously stored in a protocol buffer.

ipns.validate(publicKey, ipnsEntry, [callback])

publicKey (PubKey RSA Instance): key to be used for cryptographic operations.
ipnsEntry (Object): ipns entry record (obtained using the create function).
callback (function): operation result.
function validateIpnsRecord(entryData, keypair){
    ipns.validate(keypair.public, entryData, (err)=>{
        //if no err then the validation was successful
            console.log('\nIPNS Record Validation Successful\n');


The above code is commented enough to be self-descriptive…You can also check out the full project here.

If you want to dive deep to know how routing works in IPFS, you can read this thread. I wanted to explain this in the post, but there are too many other interesting things to explore, so I skipped it ;)

Playing with IPNS

Let’s publish our website via IPNS.

ipfs name publish QmYVd8qstdXtTd1quwv4nJen6XprykxQRLo67Jy7WyiLMB

This can take up to a few minutes. You will get an output like this:

Published to Qmb1VVr5xjpXHCTcVm3KF3i88GLFXSetjcxL7PQJRviXSy: /ipfs/QmYVd8qstdXtTd1quwv4nJen6XprykxQRLo67Jy7WyiLMB

Now you can get the latest website here:


Note: IPNS forgets(Time to Live System) published names after about 12 hours. You might want to run a cron job to republish within 12 hours.

If I want to add an updated CID, I will just use the same command:

ipfs name publish <my_new_CID>

You can also check the current CID linked to your peerID:

ipfs name resolve Qmb1VVr5xjpXHCTcVm3KF3i88GLFXSetjcxL7PQJRviXSy

This will return you the latest CID.

For added flexibility, you can also use different keys for different content and/or contexts(like below key name is

). For instance, I could publish my website using one key, my blog using another, and my talk videos using yet another.

ipfs key gen --type=rsa --size=2048 vasa_blog
ipfs name publish --key=vasa_blog <cid_to_my_blog>

This solves one of the problems that we stated above(problem with immutable links). But the links are still ugly. To make the links we still need to use DNS. There are other systems which are better suited for content-addressed systems, like CCN/NDN, XIA. But these require upgrading the internet itself, which is really hard to warrant without massive demand. Even with large demand, IPv6 has yet to be fully deployed :( — which does not give me any hope of seeing NDN/CCN massively deployed in the core, without FIRST establishing the use of content-addressed networks.

Meaning that end developers (web developers) must be able to use content-addressed networks to move lots of data (video, etc) extremely effectively well before substantial demand to improve the underlying network will materialize. So as we see it, by making IPFS usable to end developers we can create demand for these architectures as well.

Anyways, for now, let’s use DNS to create readable links.


DNSLink uses DNS TXT records to map a domain name(like

) to an IPFS address. Because you can edit your DNS records, you can use them to always point to the latest version of an object in IPFS (remember that an IPFS object’s address changes if you modify the object). But we don’t want to change the TXT records every time we update our website. So we will add an ipns link rather than an ipfs link. Also, because DNSLink uses DNS records, the names it produces are also usually easy to type and read.

A DNSLink address looks like an IPNS address, but it uses a domain name in place of a hashed public key:


Just like normal IPFS addresses, they can include links to other files:


When an IPFS client or node attempts to resolve that address, it looks for a TXT record for

with content like:

dnslink=/ipfs/<CID for your content here>
dnslink=/ipns/<hash of public key>

For example, if you look up

’s DNS records, you’ll see its DNSLink entry:

$ dig +noall +answer TXT vaibhavsaini.com

vaibhavsaini.com. 1 IN TXT "dnslink=/ipns/Qmb1VVr5xjpXHCTcVm3KF3i88GLFXSetjcxL7PQJRviXSy"

Based on that, this address:


Will get you this block:


Super Cool!

Till now we reduced our address from a complex hash to a readable name.

But, we can do better.

This(the above link) is still pretty messy, and frankly, if we want the average Web2 user of today to access my decentralized Web3 content with minimal effort, we don’t want them to have to deal with gateways and ipns/ipfs prefixes if they don’t have to. A major feeling of the decentralized web community is that the user experience shouldn’t change all that much — the transition should be transparent but easy — that’s how the decentralized web will win. Ideally, we’d like to get to something like this:


Publishing via a Subdomain

So in order to make our address more readable, we can create an A record pointing our sub-domain to the IP address of an IPFS peer listening on port 80 for HTTP requests (such as any of the public IPFS gateways, or your own if you want).

But wait, we can do even better than this!

Because we don’t want to rely on IP addresses being static, we can use a

record to point at the DNS records of the gateway. That way, if the IP address changes, we’ll still point to the right place. Unfortunately,
records don’t allow for other records (like
), but the fine folks at IPFS allow us to create a DNS
record for
, which IPFS will look for.

This is also useful when you want to improve the security of an automated setup or delegate control over your DNSLink records to a third-party without giving away full control over the original DNS zone.

I am using AWS Route53 for my DNS settings; you can use any provider.

Setting CNAME record



TXT record:


Here is how it finally looks:


And Voila! We have our content hosted and resolved using IPFS stack, with an address which can be used by any Web2 user with ease.

You may notice the “Not Secure” warning on the address bar, which is due to the fact that I haven't installed a wildcard certificate ;)

You may notice that the websites take some time to resolve. This is due to the fact that the content for your website is on just one node. If you pin your website on several nodes or other nodes try to access your website(which means your content is popular) it will resolve faster :)

That’s it for this part. In the next part, we will explore Multiformats. You can check it out here.

Thanks to Carson Farmer, Mark Pors, Jonybang for their articles[1,2,3].

Thanks for reading ;)

Learned something? Share and help others find this article.


About the Author

Vaibhav Saini is a Co-Founder of TowardsBlockchain, an MIT Cambridge Innovation Center incubated startup.

He works as Senior blockchain developer and has worked on several blockchain platforms including Ethereum, Quorum, EOS, Nano, Hashgraph, IOTA etc.

He is a Speaker, Writer and a drop-out from IIT Delhi.

This article was first published on our open-source platform, SimpleAsWater.com. If you are interested in IPFS, Libp2p, Ethereum, Zero-knowledge Proofs, DeFi, CryptoEconomics, IPLD, Multiformats, and other Web 3.0 projects, concepts and interactive tutorials, then be sure to check out SimpleAsWater.

Want to learn more? Check out my previous articles.

Follow me on Twitter: @vasa_develop

react to story with heart
react to story with light
react to story with boat
react to story with money
Vaibhav Saini HackerNoon profile picture
by Vaibhav Saini @vasa.Entrepreneur | Co-founder @tbc_inc, an MIT CIC incubated startup | Speaker |https://vaibhavsaini.com
Invite me as a Speaker
. . . comments & more!