The idea came to me as a joke about a friend who lived entirely in
git. Then I built it. tl is a social network where
every post is a commit, every friend is a submodule, and your
timeline is a git repository. It is not a toy that looks like git.
It is git. The tool is just the interface that makes the
repository behave like a timeline.
For hackers, by design
From the start the design target was clear: a social network for
people who already live in a terminal. There is no app to open, no
feed to scroll, and no algorithm to keep you staring. You type
tl post, tl list, tl follow,
tl sync, and what happens is honest work you can
watch. The backend is git, the same tool that has been versioning
human knowledge for decades. There is no server to deploy, no
database to tune, and no proprietary format to lock you in.
$ tl create --repo main --pull-url https://example.com/alice/timeline.git \
--push-url [email protected]:alice/timeline.git
$ tl post "hello, timeline"
$ tl follow https://example.com/bob/timeline.git --alias bob
$ tl sync
Every post is a commit
A post is a commit whose message is the text; attachments become
the commit's content. A reply is a commit that names its parent. A
repost carries the original commit object, signature and all, so a
shared post stays verifiable forever. Follows are commits too,
recorded in the timeline's .gitmodules, which turns
out to matter more than it sounds. And because the repository is
real, you can reach under the tool at any point:
tl git log is a perfectly ordinary git command. The
data is the history.
You cannot censor a repository
Here is the property that makes tl feel different. A
timeline is a repository with a pull URL and a push URL, but no
authority anywhere says that URL is the one true copy. Every clone
is a complete timeline. If a host disappears, someone with a copy
publishes it somewhere else, tl follow points at the
new URL, and the network is unaffected.
Any git copy can be re-uploaded as a mirror at a new address, which is why the network is structurally resistant to censorship: blocking it means blocking git itself. There is no central point that can hold the network, because there is no central point, period. Just repositories, each one as authoritative as the last copy you synced.
Censorship assumes a center. A repository has none.
Identity is a hash, not a name
There are no usernames to register and no real names anywhere in the protocol. A repository is identified by its URL, and a user is identified by the SHA3-256 digest of that URL, a fixed 64-character hex string. The same URL always resolves to the same id, on any machine, forever. You never collide with someone else's username, because you do not have a username.
You can hold several repositories, one for work and one for everything else, and give each a friendly name in your own config. The same goes for the people you follow: aliases live in your config file and are never pushed to any timeline. Names are a local comfort, not a global fact.
Following is consent, so spam cannot exist
Most networks treat your feed as an inbox anyone can shout into.
tl treats it as a repository you control. To see
someone, you follow them, which adds their timeline as a submodule
inside your own repository, in the FOLLOW/ folder.
Nothing arrives on your timeline unless you added it there, which
means there is no channel for spam or unwanted messages at all.
The same logic governs private mail: you cannot message someone you do not follow, and the tool refuses if the recipient publishes no public key. The follow mechanism lives on the host, and the host is you.
Encrypted and signed, end to end
Privacy is not an add-on, it is in the storage layout.
tl crypto --pqp gives your repository a post-quantum
keypair, ML-KEM-768 and ML-DSA-65; --gpg gives it a
classic OpenPGP key. The public key is committed to the root of
your timeline as PUBKEY, PQPKEY and
PGPKEY, so anyone who follows you can grab it with
tl sync. The private key never lives in a repository:
it sits in a keyring under the data directory, imported by hand.
A direct message is encrypted with the recipient's public key and committed as ciphertext to a branch named with their SHA3 id. The plaintext never touches the branch, only an encrypted blob:
$ tl message bob "did you see the announcement?"
encrypted message sent to `bob` on branch `3f9a2c07`
Because both sides publish keys and both sides control their
repositories, two people can hold a fully secret conversation,
end to end, with no server in the middle to read it. Signing works
the same way: tl post --sign embeds the signature in
the commit's gpgsig header, the standard git signing
slot, and tl verify checks it against the author's
published key. Post-quantum is preferred for the same reason it
comes up everywhere else on this site: ciphertext that must
outlive its key.
Discovery without a directory
If the network has no center, how do you find anyone? Follows are
public, because every timeline records who it follows.
tl discover walks that graph, your follows, the
people they follow, and so on, and lists every repository it finds
with its URL and its distance from you. You can also use a public
directory if one exists.
Either way, discovery is people, not an algorithm: you jump between the follows of the people you already trust. There is no feed, no trending, and no recommendation engine. Just a graph you can walk.
What I gave up
The trade is real, and it is the point. There is no web app, no
mobile client, no like button, and no way for the world to find
you unless someone shares your URL. The audience is small, because
the entrance exam is a terminal and a git account. Notifications
only happen when you run tl sync.
But in exchange you get a social network that is a set of files you already know how to back up, encrypt, sign, fork and mirror, one that cannot be taken down by a company decision or a court order, because it is not a company. It is the same trade as the rest of this site: a little more work on the setup, a lot more ownership forever. The full source lives on GitHub.