Updated 24 May 2026: since Discord's age-verification announcement, Fluxer now runs on a larger hosted deployment, has a small team, has started Visionary testing for native mobile, and has put self-hosting near the top of the roadmap. The Gateway was split from a monolithic cluster into six specialised tiers during a scheduled maintenance window on 24 May 2026.

I'm Hampus Kraft, a 23-year-old software developer from Sweden, nearing completion of my BSc in Computer Engineering at KTH Royal Institute of Technology. You can find my LinkedIn page here. In Sweden, our resident and company registration databases are public records. I'm an open book!
Ever since the pandemic hit in 2020, while I was still in senior high school, I've been fascinated by Discord, the instant messaging and VoIP chat app that became the default home for so many online communities.
Fluxer is the community chat app I kept coming back to for five years: familiar enough to feel useful, free and open source (AGPLv3), and built so people can run their own instance.
Fluxer in 60 seconds
Why use Fluxer when Discord is free and works well? And, realistically, why trust a new app that could disappear next week?
If Discord does what you need, and you're fine relying on a proprietary, investor-driven app that has reportedly filed confidential IPO paperwork, then you may not need Fluxer. I want to build something good enough to matter next to Discord.

Fluxer is for people who want a different deal: free, open source, self-hostable software, with an optional hosted instance run by an independent European company that helps pay for the open source work. You should not have to give up the basics you like just to leave Discord: Fluxer keeps the familiar shape of modern community chat while making the software open and self-hostable.
Fluxer can succeed without Discord getting worse. Discord's network effect is hard to beat head-on, so I'm starting where switching is already plausible: technical users and communities that value control and transparency, and want software they can run on their own terms. But you do not need to be technical for Fluxer to be yours: many people simply prefer a European-owned instance with clearer incentives and no appetite for squeezing users.
Fluxer is free and open source (AGPLv3), and it's always the same software. That is also the real answer to "why trust a new app that could disappear next week": the code is public, anyone can run it, and no community has to depend on one company surviving. The hosted instance should fund infrastructure and development work that also helps the open source project, without turning self-hosting into a trap or hiding important features behind licence checks:
- Fluxer.app is the hosted instance. It's free to use, and Plutonium gives hosted users higher limits while helping pay for infrastructure, support, and open source development. We also offered a limited-time lifetime Visionary plan for early supporters; it sold out at around 1,000 copies before we stopped it!
- We accept donations from people and organisations who self-host Fluxer, or who simply want the open source project to keep improving.
- For people who self-host and want a closer community around it, we will offer a one-time Operator Pass at $199 or €199. It helps fund the open source work and gives self-hosters a smaller place to get help from other self-hosters and the Fluxer team, share ideas, and make feedback heard before it gets buried on GitHub.
- Managed hosting comes later. Right now, the priority is making self-hosting reliable first.
If the hosted free tier limits are too tight, you can always run your own instance. Fluxer will keep the software free of feature paywalls and licence key checks. It does not force upgrades to unlock quotas on software you run yourself. No SSO tax!
Now, my backstory
2017 to 2020
I started using Discord in 2017, and my interest only grew. By January 2019, I had joined Discord Testers, their crowd-sourced bug reporting programme, and by April 2019 I'd earned enough XP to unlock the Bug Hunter badge. Around the same time, I was accepted into Discord's HypeSquad Events programme, though I never got the chance to represent Discord at any events.
2020 to 2022
When the pandemic hit, studying from home gave me a lot more time to learn. Until then, I had treated programming casually, but the project I had in mind kept pulling me back.
During my senior high school years, I worked on early prototypes of what is now Fluxer. My final graduation project became that prototype, plus a technical report on what I'd learned from studying Discord's technical blog posts and architecture and how I applied those ideas in practice. When I graduated in summer 2022, I received a small $200 scholarship from the school, and the title "Web Guru of the Year."
2022 to 2023
I've been a student at KTH Royal Institute of Technology since autumn 2022. By summer 2023, I decided to focus more actively on Fluxer, but my studies still took up much of my time, so progress was sporadic.
In October 2022, I co-authored a medium-severity bug bounty report for a permission bypass vulnerability and submitted it to Discord's security team. The report earned my co-author and me a shared award of $1,500.
While studying, I also led web development for a popular Minecraft: Bedrock Edition server with nearly 6 million registered players. I built and ran the web systems, working on API design, security, billing, and reliability. It taught me how to keep large services running, and I still help maintain those codebases when needed.
2023 to 2024
In July 2023, I released the first private alpha of Fluxer to a few dozen testers. Since then, I've iterated on the tech stack many times before settling on what I run today.
The current stack is heavily inspired by Discord and, to some extent, WhatsApp. It uses boring, proven pieces for realtime delivery, internal messaging, fast shared state, and durable persistence. I did try simpler alternatives because I wanted less complexity, but I kept reinventing the wheel for problems that proven technologies already solve well.
Those iterations, along with continued research into Discord's architecture, paid off. I dug through Reddit and Hacker News posts from Discord employees, public conversations with their engineers, and a lot of blog posts and postmortems, then tested the ideas in code to see where they held up. In parallel, my KTH studies in computer science, network security, software testing, and distributed systems gave me a strong technical foundation.
My degree programme also emphasises applying knowledge in practice. In spring 2024, I joined a project course where we delivered an internal tool for Giesecke+Devrient, an international security technology company.
2025
In January 2025, I grew wary of how Discord handled my personal data and where the app was headed. I built Discorch, a tool that guides you through Discord's undocumented privacy request process to bulk delete messages. It produces a CSV plus instructions for contacting Discord's privacy team to request deletion.
As more people used it, Discord kept changing the process and eventually restricted it, including blocking deletion of your own DM messages through this route because you can still delete those manually. The route now only works for servers and groups you have left.
In spring 2025, I reported a security vulnerability to Discord that could have enabled unauthorised destructive actions against critical user-owned data without proper authentication, and I was awarded $2,000. Later that summer, I registered Fluxer Platform AB, a Swedish limited liability company, which required a minimum deposit of $2,000.
By summer 2025, I had finished most of my university courses and spent the summer writing my bachelor's thesis with a fellow student for the supportive and welcoming Intelligent Heart Technology Lab at KTH. The thesis was published in September 2025.
Between September and December 2025, I worked day and night to make Fluxer ready for public release. Getting the architecture, feature set, and web client ready for real users by myself was the hardest work I had done.
On 25 October 2025, I opened the first private beta because I needed funding to keep going. It was a small group of around 30 testers who could invite people they knew, and a handful bought Visionary at $299 each while I worked towards feature completion.
2026
On 2 January 2026, I opened Fluxer up to everyone. I tried a Show HN, which did not go far, and launched on Product Hunt, which gained a little more traction. A few more people bought Visionary, enough to keep me going, and I started polishing things towards a self-hosting release.
There was effectively no marketing. Then a Bluesky post after Discord's IPO plans leaked travelled further than expected, and Discord's age-verification announcement on 9 February 2026 changed the scale of the project overnight. Fluxer grew to about 195,000 users, with a peak of around 11,000 concurrent connections, while the hosted setup was still built for a much smaller load and I was the only full-time engineer. In a real sense, 9 February 2026 is Fluxer's true birthday.
After Discord's age-verification announcement, Visionary sold out quickly: around 1,000 copies at $299 each before we paused sales. Visionaries are recognised in-app with a numbered badge that shows how early they supported Fluxer.
Visionary was never about FOMO; I had no idea what was coming. I capped it at 1,000 slots with an expiration date in October 2026 because that felt like a ceiling I would never come close to. I honestly expected to sell maybe a quarter of that by then at best. Selling out in a matter of days was the last thing I expected.
Fluxer feels familiar and has the features people expect from modern community chat. In a lot of areas it already does more than the other open source options, and it feels close to classic Discord.
The team is still tiny, but Fluxer is no longer just me keeping everything standing up alone. The goal remains the same: free and open source software under the AGPLv3, self-hosting without licence-key checks, and a hosted instance whose job is to serve users and fund the open source work.
You can support Fluxer through Plutonium, a custom donation, or future issues and PRs in the GitHub repo once the growth-spike cleanup is published and regular open development resumes. That support goes into infrastructure, documentation, code review, and the work needed to keep both Fluxer.app and the self-hosted release moving.

Fluxer's backend (hello Mike!)
Discord's backend scaling work is unusually well documented, and their engineering posts have been a major reference point for me. Start here:
- How Discord Scaled Elixir to 5,000,000 Concurrent Users
- Using Rust to Scale Elixir for 11 Million Concurrent Users
- How Discord Stores Trillions of Messages
- How Discord Reduced WebSocket Traffic by 40%
I have a lot of respect for their engineers, even if I'm less enthusiastic about some of Discord's business decisions. Meanwhile, a usable self-hosted alternative still doesn't really exist, and building something good enough to replace what people already use takes an enormous amount of time and energy, since people usually only pay once an app already feels close to what they expect.
What kept me going was a slightly obsessive desire to understand Discord's architecture in depth: Hacker News and Reddit threads, postmortems and blog posts, relevant courses at KTH, and professional experience along the way. I've also been active in Discord's meta communities for years, alongside fellow enthusiasts, security researchers, and bug hunters, and I've spoken with Discord engineers directly on several occasions.
That insight into Discord's development, and into people's frustrations with it, is what I'm putting to work on a real alternative to proprietary community chat apps. Fluxer should be much more than a Discord clone.
What the backend looks like now
At launch, I described Fluxer as mostly TypeScript with a bit of Erlang. That was accurate at the time. Today Fluxer.app is a small set of services, because different parts of the app need different constraints. I'm leaving out the public website and operations tooling here, since this section is about the chat app itself.
Most of what people touch every day goes through the API. It is a TypeScript service running on Node with Hono, and it owns the parts of Fluxer that change the most: accounts, authentication, communities, channels, messages, attachments, billing, reports, downloads, unfurls, and the public HTTP API. I want that code to stay easy to follow, because it is where most day-to-day app work happens. Cassandra stores durable data, Valkey handles fast shared state, and NATS carries internal messages. The Worker uses the same TypeScript stack and takes care of jobs that should not slow down a request: attachment expiry, CDN purges, search and discovery refreshes, billing reconciliation, trust and safety list syncs, scheduled messages, data exports, and bulk message deletion. Those jobs flow through NATS JetStream, with a small cron scheduler feeding the periodic ones.
The Gateway is where Fluxer stops looking like a normal web app. It is plain Erlang on OTP 28, and it owns the live side of the system: WebSocket connections, sessions, event fanout, presence, guild routing, voice and call state, and push notification delivery. In production it is split into six specialised tiers. One stateless websocket tier accepts connections, runs heartbeats, and relays frames. Five stateful clusters handle sessions, guilds, presence, calls, and push. Every node joins one distributed Erlang cluster discovered through headless Kubernetes DNS, and rendezvous hashing routes each session and guild to an owner node, then to a shard inside that node. Because the websocket tier holds no state, it can be rolled without disturbing live sessions or guilds.
Media lives in Rust because it is CPU-heavy, memory-sensitive, and exposed to untrusted input. The Media Proxy runs on axum and Tokio and handles uploads, thumbnails, metadata, transforms, external media, static files, and the upload relay. The heavy lifting goes through libvips, libheif, and FFmpeg behind a hand-written C shim, with Rust wrapped around it for memory safety, strict input limits, bounded concurrency, and request coalescing. If a hundred people open the same image, they share one transform instead of making the system do the same work a hundred times.
Rust also sits behind the API for the hot data paths being moved out of the TypeScript monolith. In the code that is public today, that means services for users, messages, full-text search, link unfurling, and Snowflake ID generation, modelled on the data services Discord built between its API and its database. They share a NATS-based RPC framework with rendezvous-hashed shards, short-lived L1 caches, and single-flight request coalescing where it helps. The database-facing services reduce repeated reads against the persistence layer, search uses an embedded Tantivy index with snapshot and restore support, and the Snowflake service uses the same 2015 epoch and 64-bit layout as Discord's, so IDs sort by time the same way.
The last piece is how everything talks. NATS carries API-to-service and API-to-Gateway RPC plus the background job stream, and the Gateway calls back into the API over HTTP to build your initial state when you connect. Valkey handles caching, rate limits, distributed locks, cache invalidation, pub/sub, and small operational queues.
The API and the Gateway own different halves of the system and call each other constantly. The API is the authority for accounts, permissions, billing, and app data. The Gateway is the authority for live sessions, routing, presence, and real-time delivery.
A note on GitHub: the remaining repository cleanup is mostly fallout from the sudden growth, which forced urgent operational and anti-abuse work while we kept the hosted service stable. We are splitting Fluxer.app deployment settings from reusable server code, documenting the settings instance operators need, and publishing the operator tooling people need to run Fluxer themselves. The public repository will include Docker images and self-hosting docs. After that, normal development happens in the open.
A typical self-hosted deployment is much smaller than the hosted setup. The Kubernetes clustering and role-split tiers described above are specific to Fluxer.app; you should not need to recreate my production cluster to run your own instance. The small setup keeps the app services together and needs only a database, Valkey, and NATS. Documented Docker images and an interactive setup command walk you through configuring an instance in your terminal. Small instances can run on a Raspberry Pi.
At launch, the Electron desktop app will support connecting to custom backends through in-app account switching, so you can run your own instance and use it from the regular desktop client without waiting for full federation.
Why three languages?
A polyglot backend sounds like a maintenance tax, and it can be. It pays off here because the three languages line up with three very different kinds of work, while the fast-moving majority of the app stays in just one of them.
Most of Fluxer is ordinary app code: accounts, permissions, billing, moderation, settings, REST endpoints. It is I/O-bound and changes constantly, so what matters is how fast one person can move through it. That work lives in TypeScript, end to end. The same language runs the API, the Worker, and the web and desktop clients, and they share types, validation, constants, and even a Discord-compatible Markdown parser (written in Rust, compiled to WebAssembly) across the wire. One person can follow a feature from a button in the client to the row in the database without switching mental models. For a codebase built mostly by one developer, that shared surface is the biggest reason I can keep moving fast.
The real-time layer is a very different problem: hundreds of thousands of long-lived connections, each needing isolation, supervision, and cheap concurrency. Erlang/OTP was built for exactly that, and trying to rebuild it in a general-purpose language is how you end up living Virding's First Rule (quoted below). Discord and WhatsApp both proved the model at a scale Fluxer will not reach for years.
The third kind of work is CPU-bound and sensitive to latency and memory: decoding untrusted media, and shielding the database from read amplification. There, a garbage collector and an interpreter get in the way. Rust gives predictable memory, no GC pauses, safe concurrency, and a safe way to wrap the C media libraries. It is also the language Discord reached for when the BEAM VM's garbage collector struggled with large data structures.
So the split is: keep the fast-moving majority in the language that lets me move fastest, and only pay for a specialised runtime where the work really needs one. A small team keeps moving while the parts that need to scale have room to scale.
Why choose Erlang/OTP?
The Erlang runtime system is designed for distributed, fault-tolerant, soft real-time, highly available, non-stop applications, with hot swapping to change code without stopping the system.
It was originally developed as proprietary software at Ericsson, a Swedish telecom company, by Joe Armstrong (who wrote his PhD thesis at my university, KTH, in the year I was born), Robert Virding, and Mike Williams in 1986. It was released as open source in 1998 and is maintained by the OTP unit at Ericsson.
Notable large-scale users include WhatsApp, plus Discord via Elixir (which compiles to bytecode for the same BEAM virtual machine that Erlang runs on). WhatsApp is far larger than Discord: more than 3 billion MAU, largely built on Erlang, with a famously small engineering team.
I tried several real-time architectures before accepting this rule:
"Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang."
Robert Virding, co-creator of Erlang
Fluxer's real-time system works roughly like this. It is heavily inspired by Discord and wire-compatible with enough of Discord's protocol to make porting existing Discord gateway bots easier:
- When you connect to the stateless websocket tier, you're asked to identify yourself with your authentication token.
- A "session manager" handles the payload. Rendezvous hashing decides which node on the sessions tier owns your session, and that node sends an authenticated HTTP request over the internal network to the API monolith's RPC endpoint to validate your token.
- If you're correctly authenticated, the API constructs everything needed for your "ready" payload and initial client state, along with an array of all guild IDs you belong to. This reads from the database in parallel and hits caches when it can.
- Your Session GenServer monitors your Presence GenServer and the Guild GenServers for the guilds you belong to. The Presence GenServer is the ingress point for direct user dispatches, so events fan out to your connected sessions only. Monitoring on both sides lets each process clean up when the other exits.
- The Guild GenServer keeps an up-to-date cache of guild properties, members, channels, and roles from API dispatches, so it can work out which sessions should receive an event scoped to a specific channel.
- Each Session keeps an in-memory buffer of received events, so a client that briefly loses its network connection can replay missed events instead of rebuilding its entire "ready" state. Connected WebSockets periodically acknowledge received sequence numbers to truncate that buffer.
- Messages that mention you are queued for mobile push notifications, and the queue is truncated as you read them. If you're away from your desktop and not active on mobile, Fluxer may send pending push notifications for messages you haven't read yet.
- Fluxer avoids sending unnecessary member and presence updates. Updates are lazy and incremental instead of full snapshots, and payloads are zstd-compressed. This is the same direction Discord went when they cut their WebSocket traffic by 40%.
A big guild's member list can hold hundreds of thousands of entries that change constantly, and your client only ever wants a small, sorted slice of it. Fluxer keeps the member rows in ETS, but the sorted index behind rank and range reads lives in a Rust NIF, just like the approach Discord described when their BEAM-side sorted member list created too much garbage-collector and allocator pressure. The NIF owns a compact order-statistic tree, so Erlang keeps supervising the guild process while Rust handles the insert/delete/rank/range work that needs predictable memory behaviour.
Once this architecture has been tested with a larger number of real users, I'll write a series of blog posts on how it works and the challenges I ran into. Kudos to the engineering team at Discord for the inspiration!
Why choose Cassandra?
Fluxer.app uses Cassandra in production today. Self-hosting is being designed to support Postgres too, because smaller instances should not have to run the same database setup as the hosted service.
For a long time, ScyllaDB was my database of choice, and Discord also migrated to it after running Cassandra. As of December 2024, though, ScyllaDB is no longer open source software, which is a deal-breaker for me.
On the other hand, I'm not sure I would have chosen ScyllaDB for Bluesky PBC's infra if there wasn't an open source version.
So this is unfortunate but I can't blame them for doing what they need to do.
Why We're Moving to a Source Available Licence - ScyllaDB
ScyllaDB is moving to a source available licence. Learn why, directly from CEO and co-founder Dor Laor.
No database is perfect, and Cassandra and I have a love-hate relationship. I keep using it because it fits Fluxer's write-heavy, event-driven design.
First, Cassandra makes it hard to be accidentally inefficient. You have to think upfront about how your data is modelled and queried, because inefficient queries are either impossible or very explicitly opt-in (hello, ALLOW FILTERING).
Second, Cassandra prioritises high write throughput, and Fluxer is built to keep reads low. When you send a message, the database does very little: it validates your auth session (a read usually served from cache) and writes the message row. Permissions are answered by the Erlang Gateway over RPC, which keeps an in-memory cache of everything needed to compute permissions in a community (called a guild internally), so a permission check is a fast internal call instead of a query. Clients mostly read from the database when starting a new session to populate initial state; after that, everything stays in sync through the event dispatching system.
Third, operationally, Cassandra removes an entire class of problems I've struggled with in traditional RDBMS setups at hosted-service scale. Postgres is the right direction for smaller self-hosted instances because people already know how to run it, but Fluxer.app has different constraints. Cassandra keeps the hosted deployment away from JOIN planning, index tuning, lock behaviour, and migration downtime. Schema changes are always zero-downtime and there are no locks. I like that!
Finally, Cassandra fits Fluxer's message rows. Unfurled links, file attachments, and similar metadata work well as embedded documents. Cassandra gives you rich types like sets and maps, along with user-defined types that can be nested, typed, and stored efficiently, so a single document does not need extra table queries or untyped JSON blobs.
Building Fluxer's hosted data model around relational joins never felt right. The app is already shaped like an event-driven document and key-value system, so a NoSQL database fits the hosted service better.
You mentioned Postgres for self-hosted instances?
Yes. The persistence layer is being shaped around a backend-neutral description of what each query does: the key, the action, and the columns. Cassandra is the hosted production backend today, and the same query model is meant to support Postgres for self-hosted instances.
Because Cassandra behaves like a key-key-value (KKV) store (partition key + clustering key, where the clustering key identifies a specific row within a partition), I already had to design my tables and queries so that every lookup requires the full key, or at least a sufficiently specific leading part of it for SELECT queries.
In Cassandra, secondary indexes are typically implemented at the application level using additional tables optimised for alternative access patterns, maintained on writes via logged batches, with optional denormalisation depending on how important it is to skip an extra read for the full primary row. Materialised views and native secondary indexes exist, but their caveats can make them risky in production.
Given those constraints, Postgres support can use a single key-value table without relying on its relational features: treat Postgres as a blob store keyed by the same enforced keys as the hosted database, with efficient prefix range queries for listing and scans, reusing the shared query builder.
I'm open to adding support for other databases too. With this abstraction finished, Fluxer can support more persistence backends without rewriting the API around each one. Some backends may use a simple table of serialised records rather than a database-specific schema, and that is fine for smaller instances.
Fluxer's frontend (have mercy!)
Fluxer's web app codebase is complex, and it deserves care. The PWA has improved a lot in the canary client and no longer feels like the rough first version from launch. To try the newest client work, use the canary desktop build at canary.fluxer.app/download or the canary web client at web.canary.fluxer.app.
Canary has fixed hundreds of bugs and adds major voice and video work: screen sharing with audio, text in voice, DM call fixes, a redesigned input and output device system, more mic processing controls, and DeepFilterNet3 noise suppression.
The web app has to handle the details people notice immediately: infinite scrolling, stable scroll position, bounded caches, jumping in time, state reconciliation, unread handling, and Discord-compatible Markdown. Those parts are tedious, but they are the difference between a familiar client and a toy.
As of 20 May 2026, the native iOS and Android app, built with Flutter, is being tested among Visionaries. Next it goes to a Plutonium beta, then a public release. The mobile app code will be open source too once it is ready to publish.
Unlike Discord, Fluxer welcomes client modifications: custom themes, non-malicious account automation, third-party clients, and anything else that tickles your fancy. It is all open source anyway, so you are welcome to upstream things that align with the goals of the project. Just open an issue first to discuss it :)
Electron? Right to jail, right away
Fluxer currently uses Electron. I know, I know. I'm not too happy about it either. Tauri is not mature enough for what I need yet, and I ran into hurdles there that I did not have in Electron. In the spirit of choosing boring technology, Electron unfortunately wins. A lot of apps give Electron a bad name, but it doesn't have to be that way.
Tauri uses the system webview. That sounds great on paper, but it leaves the desktop app at the mercy of whatever runtime the OS provides, with whatever bugs come with it. And when those bugs happen, you can't ship a fix by updating your runtime, because the runtime is tied to OS updates.
I will reevaluate Tauri when there's a mature, supported option for shipping a consistent runtime with it, like CEF (cef-rs).

For most people, Electron is an acceptable choice because it gives Fluxer a consistent desktop runtime while sharing the same client foundation as the web app.
I believe in the web platform for this kind of application. It is mature, cross-platform, well understood, and good at complex interfaces that need to run on many devices. It is also the platform I know best, which is part of why Fluxer could ship with a PWA from day one.
The first PWA had rough edges, especially on mobile, but it worked, and it has improved a lot since launch. You can see that work today in canary, and it will keep improving while the native Flutter app moves through Visionary testing, Plutonium beta, and public release.
The best mobile client is native, which is why the Flutter iOS and Android app comes first. Flutter can target desktop later, and that may become a better option than Electron for low-end devices down the line. Until then, the priority is simple: ship a reliable client that behaves consistently across web and desktop.
The LLMephant in the room
Fluxer came from about five years of work.
If you have used Fluxer and know the limits of LLMs, this should be obvious: software this large only reaches this level of quality when a competent person keeps working on it over time. In Fluxer's case, that means years of on-and-off development, testing, reworking, and learning from real users. Most of Fluxer's core predates LLMs becoming a normal part of software development, and the architecture, data model, protocols, safety decisions, technical choices, and sense of what Fluxer should be are mine.
I have real disagreements with how many models were trained and with the direction much of the AI industry is taking. Lately I've preferred local open source models where they are good enough, because the tool exists either way and I use it on my own terms.
The closest description is a second brain. When the codebase is large and the problem is subtle, it helps to have something that can sit with a crash log, a failing test, or a rough specification and help me think through where to look next. That saves time on the slow, repetitive parts of the work without changing who is responsible for the result.
The important part is that I stay in control. I decide the architecture, shape the specification, review the change, run the tests, and make sure it fits the surrounding system. If I cannot explain the change, I cannot ship it. The bar has to stay high, because Fluxer is a real app with real-time delivery, media processing, billing, moderation, abuse prevention, and user safety concerns. LLMs help me get through more work while the bar stays the same.
The clean commit history has a simpler explanation: the early work happened privately over more than three years, and I squashed it when Fluxer moved from closed development to public source. A closed-to-open transition often looks like that.
The contributor policy follows the same principle:
Understand every change in your PR. You should be able to explain what it does and why it is correct.
Keep AI-generated text out of bug reports, pull request descriptions, and GitHub comments, except for direct translation if English is not your native language.
If you use LLMs for coding help, disclose it. The contribution still needs to be understandable, reviewable, and tested well.
Contributors are welcome, and as more people work on Fluxer, LLMs should matter less to day-to-day development. With enough donations and hosted-instance revenue, Fluxer can also offer bounties for specific work. My goal is for Fluxer to become sustainable and community-developed, with more work happening outside my own todo list.
Who is building Fluxer now?
Fluxer is no longer a one-person project, but the team is still small for something this big.
I am still the only person who has worked across the whole codebase from the beginning, and I spend most of my time building the app, working on backend architecture and reliability, and handling whatever urgent production problem needs attention that day. Support, trust and safety, abuse prevention, billing, accounting, and internal tools have all spent time on my desk too.
Around that, someone is helping with direction and safety: where Fluxer goes, report review, policy work, and safety tooling. An infrastructure-focused engineer works on scaling, monitoring, CDN work, internal tooling, and voice server deployment. The native iOS and Android app has a paid contributor focused on mobile implementation, and a newer team member is taking support and billing load off my plate.
Frequently asked questions
What about the open web?
Chat apps have swallowed useful knowledge that used to live on the public web, then made it invisible to search engines, archives, and people who are not logged in.

With LLMs, Sellis said, Discord could take a long, meandering conversation and turn it into "something that could be more sharable and syndicated across the web." However, he said that he and his team hadn't "seen a solution that we feel great about yet."
Fluxer disagrees with Discord's premise here. LLMs should not turn people's "meandering conversations" into syndicated material. If something becomes public, it should be because a person or community chose to publish it.
This feature uses the web itself: public pages with stable URLs, server-rendered posts, clear titles, search indexing, archivable pages, RSS and Atom feeds, and links people can share anywhere. People's posts remain their posts.
Publishing stays opt-in, for communities that benefit from putting parts of their forum-style spaces on the open web: open source projects, developer communities, modding groups, creator communities, research groups, support forums, and any other space where public answers are meant to be searchable and useful later. Private chat stays private.
This looks a lot like Discord!
Yes, on purpose. Community chat has a shape people already understand: server list, channel list, message timeline, member list, composer, and voice controls. Discord did not invent that; it built on patterns already familiar from IRC, TeamSpeak, Slack, forums, game launchers, and older community tools.
Fluxer values a clear first screen over novelty. A Discord-like app needs to feel easy to understand for people coming from Discord. Familiarity makes switching less painful, keeps muscle memory intact, and lets Fluxer focus on the parts people actually care about: ownership, openness, privacy, performance, self-hosting, federation, safety, and incentives.
Copyright works the same way. It protects specific expression, not the general idea of putting servers, channels, messages, members, and voice controls where people expect them. In the US, 17 U.S.C. § 102(b) says copyright does not cover ideas, procedures, systems, or methods of operation. TRIPS Article 9(2) says the same internationally. EU software law says the ideas and principles behind interfaces are not protected by copyright, and the CJEU held in SAS Institute v World Programming that functionality is not expression. Nobody owns the basic pattern of a usable community chat interface.
Changing the layout only because people might compare it to Discord makes the app worse while pretending difference is the same thing as quality. Fluxer changes things where it actually improves the app; forcing people to relearn where messages, channels, servers, and voice calls live just adds friction.
I've tried a bunch of different takes on the UX, and they always end up messy. I've also tried contemporary apps that recreate the Discord experience while prioritising novelty over usability, and so have many people I've spoken to, and we keep reaching the same conclusion: they are harder to use than they need to be.
Is Discord's UX perfect? Of course not, and parts of it have got worse over time. But the older Discord model is still one of the easiest ways to understand a modern community chat app. Most open source options fail because they neither feel familiar enough to switch to nor complete enough to replace what people already use. The result may be principled, but it feels worse to most people. Classic Discord also feels nostalgic for many of us longtime users, from before the redesigns. Fluxer can improve the details while keeping a working mental model people already understand.
Fluxer can and will diverge over time. As self-hosting, public web publishing, multi-backend support, federation, moderation tooling, voice and video, and client customisation mature, Fluxer becomes more clearly its own thing. It starts from something familiar and diverges where it has a better answer.
That said, Fluxer lets you fully customise your client's look with custom CSS, and it'll continue to. More UI experiments are always appreciated!
Why the name Fluxer, and why Plutonium?
The honest origin is simple: Back to the Future is my favourite film series.
In the film, the flux capacitor is the thing that makes time travel possible. The DeLorean needs to hit 88 mph and draw 1.21 gigawatts, first from a plutonium-powered reactor. Fluxer and Plutonium are both little nods to that. Yes, naming your subscription after fictional nuclear fuel is a bit silly, which is part of the fun.
There is a more literal meaning too. Flux means change, movement, fluctuation. Chat is constantly moving: new messages, new people, new context, old conversations becoming something else over time. A chat app is almost never in a fixed state.
The logo comes from the same idea. The approximately-equal sign felt fitting because something in flux keeps changing from one moment to the next: recognisable, but always changing. I am more engineer than designer, but it has grown on us.
The slightly more dramatic reading is that the name hints toward finding a better timeline for community chat, preferably one where chat apps keep their soul without chasing an IPO.
How long did Fluxer take to build?
The first version started around 2020, while I was still in high school during the pandemic. It became my graduation project, then a long-running side project tested by friends while I studied and worked on other things.
The final run-up to public release began after I finished my bachelor's thesis in summer 2025. The private beta opened in October 2025, and Fluxer was publicly released on 2 January 2026.
The launch was quiet at first. Then Discord IPO news and Discord's age-verification announcement on 9 February 2026 put Fluxer in front of far more people than I expected. The hosted instance grew to around 195,000 users, with a peak of about 11,000 concurrent connections, while the team was still basically me trying to keep up. The team is larger now, but still small.
Why build a chat app at all?
Because I have cared about community chat for a long time. I have been deep in Discord's ecosystem since 2017: testing, reading engineering posts, following architecture discussions, reporting bugs, and talking to people who understand that world.
Fluxer started as a technical challenge but became more philosophical over time. I wanted a modern community chat app without one company controlling the app, data, network, and incentives. Self-hosters, technical communities, open source projects, and creators all need software they can trust, customise, and move away from.
I never wanted to be different for the sake of it. I wanted to preserve what people love about this kind of chat, make it free and open source, and build towards decentralisation so the future is no longer decided by one company.
I've built a Discord bot. Will it work on Fluxer?
Yesn't! Fluxer's HTTP API and WebSocket Gateway API are heavily inspired by Discord's and, in many cases, directly wire-compatible with it. That means you can reuse existing Discord libraries and abstractions in many languages.
For example, you can use the core libraries from discord.js directly. It's a bit more low-level, but it will take you very far, and the Fluxer API docs guide you through a quick start with this approach. Forking existing Discord libraries and modifying them slightly will also get you far. Or build your own community-maintained Fluxer SDK and email me (hampus@fluxer.app) to get it featured in the docs, or submit a pull request in the GitHub repository.
Note: the current docs are not where I want them to be. Brand new, complete API docs and self-hosting docs are coming soon as part of the repository cleanup.
Slash commands and similar features are still coming. If you want that work to happen sooner, Plutonium and donations help buy the time to build and publish it properly.
Why do attachments expire?
Because storage costs money, and Fluxer has no venture capital funding.
Large media adds up quickly. If every image, video, and random file stayed forever, the hosted instance would become free cloud storage with a chat app attached, which breaks the economics of a bootstrapped app trying to stay independent.
Expiry is based on file size. Small files last much longer, with the smallest lasting about three years, and files can be renewed a little when they are accessed. The exact behaviour is documented in how attachment expiry works.
Attachment expiry keeps storage under control and also protects privacy; most attachments have no reason to live forever. If you self-host Fluxer, the policy is yours to configure, including whether expiry is enabled and how much storage your instance allows.
Will Fluxer become like Discord?
I cannot make a magic promise about the future, but Fluxer's structure is designed to make that less likely.
Fluxer.app has to pay its bills and help fund the shared codebase, which is why Plutonium exists. It should be one well-run hosted instance whose income makes the software better for people who run it elsewhere too. The software itself is AGPLv3 and intended to be self-hostable, and the long-term plan includes self-hosting, data portability, multiple backends in one client, and federation. The important part is that you can leave if the hosted instance ever makes a decision you dislike.
Open source makes trust easier because leaving is possible.
Why monetise Fluxer?
Because running a real-time chat app costs real money, and so does maintaining the open source version people can run themselves. Compute, storage, bandwidth, monitoring, safety tooling, payment processing, support, and people's time all have to be paid for somehow.
The real question is who the app has to answer to. Venture capital can make an app look free for a while, but it usually comes with pressure to grow faster, extract more, and eventually answer to investors before users.
My approach is simple: keep a generous free tier, charge for higher limits on the hosted instance, accept donations from people who want Fluxer to keep going, and keep self-hosting free. Hosted revenue should buy time to improve the same app everyone can run, with the public codebase at the centre of the work.
Is Fluxer free and open source?
Yes. Fluxer is free and open source software under AGPLv3. The public repository is github.com/fluxerapp/fluxer, and the hosted Fluxer.app service and the self-hostable release should be the same app, without important features hidden away. The hosted instance pays for the work and tests it at scale, while instance operators get all the tools they need to run Fluxer themselves.
The remaining repository cleanup is mostly fallout from the growth spike, which forced urgent operational and anti-abuse work while we kept the hosted service stable. It means separating Fluxer.app deployment settings from reusable instance settings, documenting the settings operators need, and publishing the admin, moderation, abuse-prevention, and operations tooling in a form people can actually run. The care is in publishing abuse protections without turning them into a bypass guide.
Pull requests reopen once this cleanup is published, along with self-hosting documentation, Docker images, and setup guides. After that, Fluxer should be open by default.
Will self-hosting cost money?
No. Running your own Fluxer instance requires no licence key, paid tier, or special enterprise unlock. You are responsible for hosting, uptime, moderation, safety, and legal obligations, but the software itself is free to run.
The Operator Pass is a $199 or €199 one-time purchase for self-hosters who want to support the open source work and join the Operators community: a smaller place to get help from other self-hosters and the Fluxer team, share ideas, and make feedback heard before it gets buried on GitHub. It comes after the docs and setup guides are solid, and those stay public.
Federation?
Federation remains a major goal, and the order matters. People who run and use Matrix complain about specific things: large federated rooms can be slow and expensive to join, presence and device-list updates can create surprising background load, federation failures can leave rooms or encrypted messages half-working, and moderation gets harder when abuse, media, bans, and bridges cross instance boundaries.
The self-hosting release starts with account switching for custom backends in the Electron desktop app. Shortly after, the client gets simultaneous connections to multiple backends without making you switch between workspaces. The goal is one client that can show several instances together before Fluxer has the unified identity and authentication model that full federation needs.
True federation can come after that, with OAuth2-based authentication against remote instances and a clearer model for where identity and data live.
How does moderation work?
Each Fluxer instance is responsible for its own moderation. Fluxer Platform AB operates the hosted Fluxer.app instance, so we are responsible for reports, safety enforcement, legal compliance, and abuse prevention there.
The repository cleanup also covers moderation, abuse-prevention, and operator tooling that still needs to be separated from Fluxer.app-specific settings. Instance operators should get the full toolset in a form they can actually use, without making the hosted instance easier to attack.
We are also a registered electronic service provider (ESP) with access to the CyberTipline Reporting API from the National Center for Missing & Exploited Children (NCMEC).
Once federation exists, moderation stays local to the instance enforcing it. A ban on one instance stays local unless other instances choose to share or honour that signal.
Why do you follow local laws in my country or state?
For self-hosted instances, this is the responsibility of the person running the instance. If you run your own instance, you decide where you provide service and what legal risk you accept.
For the hosted Fluxer.app instance, we have to comply with the law where we serve traffic. Some recent age-verification laws are invasive enough that we restrict access instead of collecting government IDs or biometric data from everyone.
As of 24 May 2026, Fluxer restricts NSFW access in the United Kingdom and Brazil. In the UK, we can offer a less invasive optional adult check through a $0.00 credit card authorisation. Brazil currently lacks a privacy-preserving path we are comfortable with. Mississippi requires age verification for access to the whole service, so the hosted Fluxer.app instance blocks access from Mississippi instead.
The current details are kept in regional restrictions and minimum age requirements.
Where does Fluxer run?
Fluxer.app currently runs in US East on Vultr. That location gives good connectivity to both North America and Europe, which helps message loading and real-time delivery.
We are paying attention to the geopolitical issues. The US CLOUD Act and broader data-sovereignty concerns are real. Longer term, federation makes it possible to partition accounts and communities by region, including EU-only hosting, and moving more infrastructure to Europe remains an option.
Voice and video are already more distributed. Current RTC regions include Sydney, São Paulo, Santiago, Frankfurt, Stockholm, Warsaw, Madrid, Mumbai, Singapore, Seoul, Johannesburg, Newark, Atlanta, Dallas, Seattle, and Los Angeles.
What happens when Google shuts down Tenor?
Fluxer currently relies on Tenor for GIF search in the app, and Google is shutting down the current Tenor API on 30 June 2026. Fluxer already has KLIPY support in the codebase. KLIPY was built by former Tenor people and is the obvious replacement when the current Tenor API stops working.
GIFs are proxied through Fluxer either way, so the privacy promise stays the same: providers do not see your IP address just because you searched for or viewed a GIF through the app.
End-to-end encryption?
Matrix does offer E2EE, but the complexity of the protocol and its client implementations often comes at the expense of what people actually want.
Most people want a Discord alternative they can use day to day: fast clients, good search, profiles and statuses, custom emoji, roles and permissions that make sense, solid voice and video, and moderation tools that work. Fluxer's priorities are there first. Adding E2EE to text messaging makes the app much harder to build and maintain, and Fluxer is focusing first on a stable community chat app that feels as capable as Discord.
Text on Fluxer has no end-to-end encryption today. Optional E2EE is still planned where it fits: personal notes, calendar data, DMs, and small groups. E2EE for large communities is out of scope.
Voice is further along. Canary already uses LiveKit's built-in E2EE support for voice and video in enrolled testing communities. It rolls out to everyone soon, then becomes enforced as supported clients catch up.
Native mobile app?
Yes. The native app is built with Flutter for iOS and Android, and as of 20 May 2026 it is in testing with Visionaries. Visionaries get it first, then a Plutonium beta, then public release.
The Flutter app can also target desktop later, making it an alternative to Electron for low-end devices. For now, iOS and Android come first.
The canary PWA has improved in the meantime. To use the newest client work before stable, try canary.fluxer.app/download or web.canary.fluxer.app.
Can I help localise Fluxer?
Yes. Fluxer already supports 34 locales across the app, email templates, marketing site, and similar places:
- العربية
- Български
- 简体中文
- 繁體中文
- Hrvatski
- Čeština
- Dansk
- Nederlands
- English (United Kingdom)
- English (United States)
- Suomi
- Français
- Deutsch
- Ελληνικά
- עברית
- हिन्दी
- Magyar
- Bahasa Indonesia
- Italiano
- 日本語
- 한국어
- Lietuvių
- Norsk
- Polski
- Português (Brasil)
- Română
- Русский
- Español (Latinoamérica)
- Español (España)
- Svenska (Sverige)
- ไทย
- Türkçe
- Українська
- Tiếng Việt
We care about localisation a lot. We do not assume everyone speaks English, and Fluxer needs to feel usable internationally whether English is your first language or not.
Because the app changes quickly and the team is small, many translations are drafted and kept up to date with LLM help. LLM literally means large language model, and this is one place the tool fits: it saves humans from starting every locale from a blank page and helps non-English speakers get a better app sooner.
That first pass only gets us started. Native speakers catch what a model can miss: tone, terminology, awkward phrasing, and cultural details. People have told us the current localisation is already good in many languages, but we still want native speakers involved before we treat it as something people can rely on.
The next step is a self-hosted Weblate instance where localisation work can happen in the open. To improve an existing locale or add a new one, email i18n@fluxer.app and we'll put you on the waitlist.
Do you have a Contributor Licence Agreement?
No. Fluxer had a CLA early on, mostly because the expected path at the time looked more like self-hosting support and companies running Fluxer themselves. A CLA would have made it easier to offer a separate commercial licence to organisations whose policies prohibit AGPLv3 software.
After Fluxer took off as a hosted app for regular users, that deal stopped making sense. The CLA goes away when pull requests reopen with the cleaned-up codebase.
Where's the roadmap?

Closing thoughts
If you care about this too, GitHub contributions and donations help most. Notes to @fluxer.app on Bluesky are useful too, especially when something feels confusing or broken.
I want Fluxer to stay fully independent and bootstrapped, funded by donations, early supporters, and Plutonium on the hosted instance. That support funds the infrastructure, people, and cleanup work that keep the open source app healthy too.
Got questions, or want to work with Fluxer? Reach me at hampus@fluxer.app if you're a content creator, run an open source project, manage a community of any size, or can help with CDN, trust and safety, or moderation work. If you're a fellow independent, bootstrapped, privacy-first alternative to the mainstream, or you're in the press, I'd love to talk too.
I want Fluxer to become a real alternative to Discord without losing why I started building it.
See you in the Fluxerverse!



