# _ _ _ # __ _| | _____ _____ _ __ (_) |_ # / _` | |/ _ \ \/ / _ \| '_ \| | __| # | (_| | | __/> < (_) | | | | | |_ # \__,_|_|\___/_/\_\___/|_| |_|_|\__| # # Craft your dreams with your hands. # ---------------------------------- # # nick = alexonit # url = https://twtxt.alessandrocutolo.it/twtxt.txt # avatar = https://twtxt.alessandrocutolo.it/avatar.png # description = Writing code for work, fun and everything in between. # # link = Website https://alessandrocutolo.it/ # # follow = prologic https://twtxt.net/user/prologic/twtxt.txt # follow = movq https://www.uninformativ.de/twtxt.txt # follow = lyse https://lyse.isobeef.org/twtxt.txt # follow = thecanine https://twtxt.net/user/thecanine/twtxt.txt # follow = zvava https://twtxt.net/user/zvava/twtxt.txt # follow = bender https://twtxt.net/user/bender/twtxt.txt # follow = quark https://ferengi.one/twtxt.txt # follow = kat https://yarn.girlonthemoon.xyz/user/kat/twtxt.txt # follow = itsericwoodward https://itsericwoodward.com/twtxt.txt # follow = important_dev_news https://n8n.andros.dev/webhook/f0cfd6a6-60c8-4183-a26d-120bbd25a046 # follow = news-minimalist https://feeds.twtxt.net/news-minimalist/twtxt.txt # 2025-09-17T11:06:50+02:00 Hello world, everyone! 2025-09-19T08:16:35+02:00 Hello everyone! 👋

After a long while away, I'm back on twtxt with this new feed.

Some of you might remember me as `justamoment@twtxt.net`, that was a test account I made for trying things out, but I ended up keeping it more than planned.

I also tried other social platforms in search of a place that felt right for me.

In the end twtxt was the one that ticked all of my boxes:

- Slow social: it act more like a feed reader and I really appreciate that there's no flood of content that I can't keep up with.
- No server needed: I absolutely love to have total control over my content, I tend to avoid having moving parts that might break, plus you can put your feed under version control and it's all backed up.
- Ownership: I can put my feed anywhere I want and nobody can decide if I can access it or not.
- For hackers: a single .txt file allows me to join a community, how cool is that!

This is why I decided to build my own twtxt client, one that allows you to decide how the feed is presented on your "instance".

It's still in the making but I'll try to share a bit of it once I defined how things should work.

Coincidentally, I discovered that @ and @ were also building a twtxt client, seems like twtxt is set to grow! 2025-09-19T08:44:54+02:00 (#fzmmn2q) @ @ @ I also was wondering how to handle this.

Currently my regex is like this: `/@<((?[^\s]+)\s)?(?\w+:\/\/[^>]+)>/g`

It takes everything until the space and the nick is optional. 2025-09-19T08:58:34+02:00 (#dvw775q) @ @ I also think a location based reference might be better.

A thread is a single post of a single feed as a root, but the hash has the drawback of not referencing the source, in a distributed network like twtxt it might leave some people out of the whole conversation.

I suggest a simpler format, something like: `(#)`

This solves three issues:

- Easier referencing: no need to generate a hash, just copy the timestamp and url, it's also simpler to implement in a client without the rish of collisions when putting things together
- Fetchable source: you can find the source within the reference and construct the thread from there
- Allow editing: If a post is modified the hash becomes invalid since it depends on `[ timestamp, url, content ]` 2025-09-19T09:02:24+02:00 (#dvw775q) My proposal is taken from BTW. 2025-09-19T09:07:28+02:00 (#jdhwlna) @ With a progressive web app (PWA) you can have a native like experience without having to trouble yourself with building a second project that act as a client.

You can even "wrap" it into a packaged installation and publish it on stores, theres even projects to streamline it . 2025-09-19T09:11:41+02:00 (#s5wriqq) @ I kinda fixed the issue by not stripping the timestamp at all.

Seems that more feeds work correctly this way. 🤔 2025-09-19T20:52:19+02:00 While working on the [Discoverability](https://twtxt.readthedocs.io/en/latest/user/discoverability.html) for my twtxt client (it runs client-side) I found out that Chrome doesn't allow to set a custom user agent. 🙃

I thought it was a general thing for browsers, but it that was actually allowed in a newer specification, yet it's still not implemented in Chrome, it does work in Firefox though. 2025-09-21T10:33:23+02:00 (#cqzexoq) @ Me neither, if there's any important news others usually tell me anyway. 😌 2025-09-21T13:28:02+02:00 (#cqzexoq) @ thanks, I already follow @ too.

BTW, the feed on https://feeds.twtxt.net/ seem down? It says it's in maintenance. 2025-09-21T13:31:16+02:00 (#altkl2a) @ Yeah, the format is just an idea of how it could work.

The order of `SOURCE > POST` does make more sense indeed. 2025-09-21T13:36:30+02:00 (#s2lah7a) This looks so huggable, it feels like a plushie! 🥰

After seeing so many resolutions, I think you're only missing a *matrioska* version of it. 🪆 2025-09-22T12:29:04+02:00 (#s2lah7a) @ Thanks!

Looking forward to it!✌️ 2025-09-22T13:49:45+02:00 (#altkl2a) @ I can see the issues mentioned, but I think some can be fixed.

1. The current hash relies on a `url` field too, by specification, it will use the first `# url = ` in the feed's metadata if present, that too can be different from the fetching source, if that field changes it would break the existing hashes too, a better solution would be to use a non-URL key like `# feed_id = ` with the `url` as fallback.

2. We can prevent duplications if the reference uses that same url field too or the client "collapse" any reference of all the urls defined in the metadata.

3. I agree that hashing based on content is good, but we still use the URL as part of the hashing, which is just a field in the feed, easily replicable by a bot, also noting that edits can also break the hash, for this issue an alternative solution (E.g. a private key not included in the feed) should be considered.

4. For offline reading the source would be downloaded already, the fetching of non followed feeds would fill the gap in the same way mentions does, maybe I'm missing some context on this one.

5. To prevent collisions there was a discussion on extending the hash (forgot if that was already fixed or not), but without a fallback that would break existing clients too, we should think of a parallel format that maintains current implementations unchanged, we are already backward compatible with the original that don't use threads at all, a mention style format for that could be even more user-friendly for those clients.

We should also keep in mind that the current mention format is already location based (`@`) so I'm not that worried about threads working the same way.

Hope to see some other thought about this matter. 🤓 2025-09-22T13:52:15+02:00 (#orntm4a) @ Oh! A new place to spam dad jokes. 🥳 2025-09-22T17:54:31+02:00 (#bkbv6ta) @ Happy equinox!

It looks amazing from the map, you probably can't tell even by looking from space. 2025-09-23T07:34:14+02:00 (#3h7w7ca) @ @ Can't we find a middle ground and support both?

The thread is defined by two parts:

1. The hash
2. The subject

The client/pod generate the *hash* and index it in it's database/cache, then it simply query the subject of other posts to find the related posts, right?

In my own client current implementation (using hashes), the only calculation is in the hash generation, the rest is a verbatim copy of the subject (minus the `#` character), if this is the common implemented approach then adding the location based one is somewhat simple.

```js
function setPostIndex(post) {
 // Current hash approach
 const hash = createHash(post.url, post.timestamp, post.content);

 // New location approach
 const location = post.url + '#' + post.timestamp;

 // Unchanged (probably)
 const subject = post.subject;

 // Index them all
 addToIndex(hash, post);
 addToIndex(location, post);
 addToIndex(subject, post);
}

// Both should work if the index contains both versions
getThreadBySubject('#abcdef') => [post1, post2, post3]; // Hash
getThreadBySubject('https://example.com#2025-01-01T12:00:00') => [post1, post2, post3]; // Location
```

As I said before, the mention is already location based `@`, so I think we should keep that in consideration.

Of course this will lead to a bit of fragmentation (without merging the two) but I think this can make everyone happy.

Otherwise, the only other solution I can think of is a different approach where the value doesn't matter, allowing to use anything as a reference (hash, location, git commit) for greater flexibility and freedom of implementation (this probably need the use of a fixed "header" for each post, but it can be seen as a separate extension). 2025-09-25T11:38:52+02:00 (#yfma5gq) @ What?! In my country you have to pay 100€ every 10 years of which about 75% are just taxes... 2025-09-25T11:42:21+02:00 (#hmed7jq) @ I used the dates as is for indexing them as string, the ISO format allows for free auto sorting. 2025-09-25T12:50:16+02:00 (#3h7w7ca) @ That is really great to hear!

If there are opposing opinions we either build a bridge or provide a new parallel road.

Also, I wouldn't call my opinion a "stance", I just wish for a better twtxt thanks to everyone's effort.

The last thing we need to do is decide a proper format for the location-based version.

My proposal is to keep the "Subject extension" unchanged and include the reference to the mention like this:

```
// Current hash format: starts with a '#'
(#hash) here's text
(#hash) @ here's text

// New location format: valid URL-like + '#' + TIMESTAMP (verbatim format of feed source)
(url#timestamp) here's text
(url#timestamp) @ here's text
```

I think the timestamp should be referenced verbatim to prevent broken references with multiple variations (especially with the many timezones out there) which would also make it even easier to implement for everyone.

I'm sure we can get @, @ and everyone else to help on this one.

I personally think we should also consider allowing a generic format to build on custom references, this would allow for creating threads using any custom source (manual, computed or external generated), maybe using a new "Topic extension", here's some examples.

```
// New format for custom references: starts with a '!' maybe?
(!custom) here's text
(!custom) @ here's text

// A possible "Topic" parse as a thread root:
[!custom] start here
[custom] simpler format
```

This one is just an idea of mine, but I feel it can unleash new ways of using twtxt. 2025-09-25T16:40:09+02:00 (#xjvujya) @ Well, you guessed correctly! 😁

Would be nice to have a fixed fee for that, a car is a car anywhere in the world... 2025-09-25T17:00:15+02:00 (#ag5xxha) @ I admit that I was a bit confused about the meaning of the message, at least I understood it was a "yes" from the last sentence. 😅 2025-09-25T17:04:39+02:00 (#7fsi7yq) @ While it might work if you want to keep both, I think the point was to be able to use one or the other, if we still have to generate the hash anyway it might be pointless to use this format. 2025-09-25T19:04:39+02:00 (#vdkllnq) @ I think a counter in the client is not a good choice given the decentralized nature of twtxt, especially if someone use multiple cients together.

After thinking about it for a while I got to two solutions:

**Proposal 1: Thread syntax (using subject)**

Each post have an implicit and an *optional* explicit root reference:

- Implicit (no action needed, all data required are already there)
 - URL + timestamp

- Explicit (subject required)
 - Identity (client generated)
 - External reference
 - Random value

We then add include a "root" subject in each post for generating explicit theads:
 1. `[ROOT_ID] (REPLY_ID)`: simpler with no need of prefixes
 2. `(root:ROOT_ID) (reply:REPLY_ID)`: more complex but could allow expansions
 - `(rt:ROOT_ID) (re:REPLY_ID)`: same but with a compact version
 - `($ROOT_ID) (>REPLY_ID)`: same but with a single characters

Each post can have both references, like the current hash approach the reference can be treated as a simple string and don't have a real meaning.

Using a custom reference this way allows a client to decide how to generate them:
- Identity: can be a content hash or signature or anything else, without enforcing how it is generated we can upgrade the algorithm/length freely
- External references: can be provided from another system (Eg. `7e073bd345`, *yarnsocial/yarn* latest commit)
- Random value: like a UUID (Eg. `9a0c34ed-d11e-447e-9257-0a0f57ef6e07`)

**Proposal 2: Threaded mentions (featuring zvava)**

Inspired by @'s solution it could be simplified into: `#` or `#`

It can be shown like a mentions or hidden like a subject.

If we're using thinking of using a counter in the client, I think there's no point in avoiding the timestamp anymore.