2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00
2026-02-22 21:26:15 -05:00

twtxt-lib

An isomorphic TypeScript library of utility functions for parsing and interacting with twtxt.txt files.

These functions include:

  • hashTwt: takes the constituent parts of a "twt" and generates an extension-compatible hash for it.
  • parseTwtxt: parses a twtxt file string, returning an object with information about the file and its owner (including hashes for each twt and any metadata in the file).
  • loadAndParseTwtxt: fetches a twtxt file from the internet and parses it into an object (as above).

Installation

Browser

  • Download library (or minified version).
  • Import desired function(s) into your project: import { hashTwt, loadAndParseTwtxtFile } from "./twtxt-lib.js"

NPM

  • Coming soon

JSR

  • Coming soon

Features

Usage

loadAndParseText

This is arguably the most useful function:

import { loadAndParseTwtxtFile } from "/web/dist/twtxt-lib.js";

// run in an IIFE (or event listener) to avoid issues with top-level await
(async () => {
    try {
        const parsedFile = await loadAndParseTwtxtFile(
            "/twtxt-demos/demo-hipster-twtxt.txt",
        );

        console.log(parsedFile);

    } catch (err) {
        console.error(err);
    }
})();

Result:

{
  "following": [
    {
      "nick": "demo_hipster",
      "url": "https://example.com/demo-hipster-twtxt.txt"
    },
    {
      "nick": "demo_pirate",
      "url": "https://example.org/~pirate/twtxt.txt"
    },
    {
      "nick": "demo_sagan",
      "url": "https://example.net/~saganos/twtxt.txt"
    }
  ],
  "metadata": {
    "nick": "demo_hipster",
    "url": "https://example.com/demo-hipster-twtxt.txt",
    "avatar": "https://i.pravatar.cc/150?img=67",
    "description": "Kitsch ut post-ironic, bruh tilde non shabby chic iceland fixie consequat?"
  },
  "twts": [
    {
      "content": "Normcore tilde ad selfies, culpa cupping nostrud gatekeep aesthetic PBR&B 3 wolf moon mustache twee.",
      "created": "2025-06-02T18:47:01+01:00",
      "createdUTC": "2025-06-02T17:47:01.000Z",
      "hash": "ymiydvq"
    },
    {
      "content": "Cardigan jean shorts eu 90's. Kitsch knausgaard culpa, marfa mumblecore portland raclette banjo retro exercitation pariatur snackwave williamsburg.",
      "created": "2025-07-05T00:17:46+02:00",
      "createdUTC": "2025-07-04T22:17:46.000Z",
      "hash": "c6bm4sq"
    },
    ...
  ],
  "lastModified": "2026-02-22T20:56:59.000Z"
}

When using in a web browser, be aware of potential the potential for issues with Cross-Origin Resource Sharing (CORS).

hashTwt

import { hashTwt } from "/web/dist/twtxt-lib.js";

const hash = hashTwt({
    content: "Prow scuttle parley provost Sail ho shrouds spirits boom mizzenmast yardarm.",
    created: "2026-02-01T01:23:45Z",
    url: "https://example.org/~pirate/twtxt.txt",
});

console.log(`Hash: ${hash}`);

Result

Hash: 7uftieq

parseTwtxt

import { base32Encode, hashTwt, loadAndParseTwtxt, parseTwtxt } from "twtxt-lib";

const fileText = `
# nick = demo_sagan
# url = https://example.net/~saganos/twtxt.txt
# avatar = https://i.pravatar.cc/150?img=69
# description = Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit?
# finger = sagaan@example.net
# link = Web https://example.net/~saganos/
#
# follow = demo_sagan https://example.net/~saganos/twtxt.txt
# follow = demo_pirate https://example.org/~pirate/twtxt.txt
# follow = demo_hipster https://example.com/demo-hipster-twtxt.txt
#
# following = 3
#

2026-02-05T23:17:47Z	The ash of stellar alchemy permanence of the stars extraordinary claims require extraordinary evidence rings of Uranus vanquish the impossible encyclopaedia galactica?
2026-01-22T12:09:44Z	Something incredible is waiting to be known another world hearts of the stars tendrils of gossamer clouds a still more glorious dawn awaits venture.
2026-01-10T13:44:37Z	Dream of the mind's eye citizens of distant epochs a still more glorious dawn awaits preserve and cherish that pale blue dot hearts of the stars preserve and cherish that pale blue dot and billions upon billions upon billions upon billions upon billions upon billions upon billions.
2026-01-01T02:05:04Z	With pretty stories for which there's little good evidence muse about a billion trillion globular star cluster inconspicuous motes of rock and gas dream of the mind's eye.
`.trim();

console.log(parseTwtxt(fileText));

Result:

{
  "following": [
    {
      "nick": "demo_sagan",
      "url": "https://example.net/~saganos/twtxt.txt"
    },
    {
      "nick": "demo_pirate",
      "url": "https://example.org/~pirate/twtxt.txt"
    },
    {
      "nick": "demo_hipster",
      "url": "https://example.com/demo-hipster-twtxt.txt"
    }
  ],
  "metadata": {
    "nick": "demo_sagan",
    "url": "https://example.net/~saganos/twtxt.txt",
    "avatar": "https://i.pravatar.cc/150?img=69",
    "description": "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit?",
    "finger": "sagaan@example.net",
    "link": "Web https://example.net/~saganos/",
    "following": "3"
  },
  "twts": [
    {
      "content": "With pretty stories for which there's little good evidence muse about a billion trillion globular star cluster inconspicuous motes of rock and gas dream of the mind's eye.",
      "created": "2026-01-01T02:05:04Z",
      "createdUTC": "2026-01-01T02:05:04.000Z",
      "hash": "64wq3va"
    },
    {
      "content": "Dream of the mind's eye citizens of distant epochs a still more glorious dawn awaits preserve and cherish that pale blue dot hearts of the stars preserve and cherish that pale blue dot and billions upon billions upon billions upon billions upon billions upon billions upon billions.",
      "created": "2026-01-10T13:44:37Z",
      "createdUTC": "2026-01-10T13:44:37.000Z",
      "hash": "72vgpyq"
    },
    {
      "content": "Something incredible is waiting to be known another world hearts of the stars tendrils of gossamer clouds a still more glorious dawn awaits venture.",
      "created": "2026-01-22T12:09:44Z",
      "createdUTC": "2026-01-22T12:09:44.000Z",
      "hash": "bgg5rqq"
    },
    {
      "content": "The ash of stellar alchemy permanence of the stars extraordinary claims require extraordinary evidence rings of Uranus vanquish the impossible encyclopaedia galactica?",
      "created": "2026-02-05T23:17:47Z",
      "createdUTC": "2026-02-05T23:17:47.000Z",
      "hash": "qa4xrla"
    }
  ]
}

See the included tests and demo file for more information on how to use it.

License

Copyright (c) 2026 Eric Woodward, released under the MIT License.

Description
An isomorphic TypeScript library of utility functions for parsing and interacting with twtxt.txt files.
Readme MIT 401 KiB
Languages
JavaScript 82.7%
HTML 7.2%
CSS 6.2%
TypeScript 3.9%