Kandan Core: a HipChat replacement that is still mostly a plan
Kandan is an Open Source Alternative to HipChat
At a glance
- What is it?
- A self-hosted team chat rebuild on Angular 21, Express 5 and Socket.io, with the API surface and event names already designed but the Angular client still to come.
- Who is it for?
- Read Kandan's README as a design document rather than a product description. The stack table, the eight REST endpoints, the eight Socket.io events and the workspace layout are the real content, and they are coherent choices: Express 5 with Drizzle over SQLite keeps a small team chat to a single file database, and Socket.io rooms map cleanly onto the channel model that HipChat users expect.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A revival of an older self-hosted chat app
The framing sentence is that this is a modern revival of Kandan, a self-hosted open-source team chat app, and the repository is called Kandan Core to distinguish it from the original. That distinction matters for anyone who has heard of Kandan's earlier life as a HipChat alternative, because this is not a maintained fork that inherited a working codebase. It is a rewrite.
The README is unusually direct about its state, opening with a status line reading early development, backend scaffolded, Angular client coming next. That single sentence tells you what any evaluation needs to know, and it sits above the stack table rather than in a contributing guide, which is the right place for it. The repository has 2,685 stars and 389 forks with 21 open issues, which for a scaffold is a lot of attention, and it is not archived, with the last push on 2026-04-06.
What follows from the rewrite framing is that the design decisions are the product right now. The API and event names, the database choice and the split into workspaces are the parts you would inherit and argue with later. The screenshots are not.
A stack table that reads like a deliberate set of choices
The stack is laid out as a table of layer against technology: Angular 21 with TailwindCSS on the front, Express 5 with TypeScript behind, SQLite through Drizzle ORM for storage, Socket.io for real-time, and JWT plus bcrypt for authentication. Each of those is a defensible default, and two of them are worth a sentence.
Drizzle over SQLite is the interesting choice for a chat server. Most small chat deployments reach for Postgres because it is the default, and it is a reasonable default, but a team chat with a few dozen users generates a small working set of messages that a single file database handles comfortably. Drizzle gives typed queries and a migration story without requiring a separate service to keep running, which for a self-hosted project is a large share of the operational burden removed.
JWT with bcrypt is the least novel part, and the least controversial. Express 5 rather than 4 suggests the author started from a current major version instead of an inherited lockfile, and Angular 21 on the client is the same kind of choice. TailwindCSS rather than a component library is consistent with a project whose whole point is building its own interface.
Getting the server running is four commands
The Getting Started section is short, which is a good sign about how little has to be assembled:
git clone [email protected]:DamageLabs/kandan-core.git
cd kandan-core
cd server
cp ../.env.example .env # edit as needed
npm install
npm run dev # http://localhost:3200There is a real snag in those lines. The clone URL points at DamageLabs/kandan-core, while the repository you are reading is DamageLabs/kandan, so the command as written will not resolve. That looks like the repository was renamed after the README was written, or the README was written for a monorepo name that was never used. Either way, expect to clone the `kandan` repository and then `cd` into the workspace root, since the project is organised as npm workspaces.
The `package.json` in the tree confirms that layout, declaring workspaces of `server` and `client` with `kandan-core` as the package name at version 0.1.0, private, with husky wired to the prepare script. The environment file is four lines, which is a good sign about configuration surface:
PORT=3200
CLIENT_URL=http://localhost:4300
DATABASE_URL=./data/kandan.db
JWT_SECRET=change-me-in-productionNote the two different ports. The server listens on 3200 while the client origin is 4300, so the two are separate development servers, and `CLIENT_URL` is almost certainly the CORS allowlist. The `JWT_SECRET` default is named for what it is, and `ecosystem.config.cjs` at the root suggests a PM2 deployment path.
Eight REST endpoints covering the minimum viable chat
The API table is small enough to read as a specification of what the author considers the core of a team chat. Authentication is three endpoints: `/api/v1/auth/register` to create a user, `/api/v1/auth/login` which returns a JWT, and `/api/v1/auth/me` for the current user. Channels are four: list channels, fetch a channel with recent messages, and create a channel as an admin.
Then messages and users. `/api/v1/messages/channel/:id` is paginated history for a channel, and `/api/v1/users` lists users, also admin only. So the permission model is JWT plus a role check on two routes, which is the minimum that supports the admin controls listed as a planned feature: user approval, suspension and channel management.
What is missing is as informative as what is present. There is no attachment endpoint, despite file attachments appearing in the planned features list, and no endpoint for reactions or emote state. The `/me` emote commands are listed as planned and have no route, so they are presumably handled as message text and parsed server side. The API version prefix is a good sign, since it means the shape can change without breaking anyone once other clients exist.
Socket.io events mapped to rooms, join and typing
The real-time layer is eight events with directions marked, and the design is the conventional one. The client emits `channel:join` and `channel:leave` to enter and exit a channel room, then `message:send` to post. The server broadcasts `message:new` back to the room and separately emits `user:connected` and `user:disconnected` so presence updates arrive without polling.
Typing indicators get their own pair, `typing:start` and `typing:stop`, which is a deliberate choice worth noting. A shared typing indicator across multiple clients needs some way to stop: either a timer on the client or an explicit stop message. Doing it with explicit events puts the responsibility in one place and lets the server coalesce repeated start signals, which is the right call for something that fires on every keystroke burst.
The separation between REST and Socket.io is also deliberate and correct. History comes over paginated REST so it can be cached and reloaded, while only live events go over the socket. A client that reconnects after a dropped connection re-fetches history rather than trying to replay missed broadcasts, which is a much simpler failure mode.
Planned features and the two mismatches worth knowing
The planned list is nine items: real-time messaging over WebSockets, multiple channels, authentication, admin controls, file attachments, `/me` emote commands, typing indicators, paginated message history, and dark and light mode. Most of that is already designed at the API level, which is a reasonable way to sequence a rewrite: agree on the interface, then build both sides against it. Dark and light mode is the odd one out, since it is a pure client concern with nothing for the server to know about.
Two mismatches in the documentation deserve a mention, both of the kind that waste an afternoon. The clone URL names a different repository than the one hosting the README, as covered above. The second is licensing: there is no licence in the file listing, while the README states MIT in a section of its own. For a self-hosted project whose entire pitch is running it yourself, that is the kind of gap to resolve with the author rather than assume, because a missing licence file means the default legal position is not yours to rely on.
Neither of these is a reason to walk away from a project that has clearly thought about its architecture. They are reasons to send a pull request, since the client is the next milestone and the repository is open to it.
Editorial conclusion
Read Kandan's README as a design document rather than a product description. The stack table, the eight REST endpoints, the eight Socket.io events and the workspace layout are the real content, and they are coherent choices: Express 5 with Drizzle over SQLite keeps a small team chat to a single file database, and Socket.io rooms map cleanly onto the channel model that HipChat users expect. The gap is the client. The Angular application is listed as coming next, so nothing here is usable as a chat product today, and the README says so in a status line rather than burying it. Two details to sort before you trust the docs. The clone command points at a kandan-core repository rather than kandan, and the metadata records no licence even though the README states MIT. The last push was on 2026-04-06, which is recent enough to suggest the scaffold is still moving.
Frequently asked questions
What is Kandan Core and how does it relate to the original Kandan?
Kandan Core is a rewrite of the self-hosted Kandan team chat app, described as a modern revival of it. It is not a fork carrying the old code: the backend has been scaffolded fresh on Express 5 and TypeScript, with an Angular 21 client listed as the next piece of work.
Can I run Kandan Core today?
Not as a usable chat product. The README states the project is in early development with the backend scaffolded and the Angular client still to come, so there is currently no interface to chat through. The stack table, API endpoints and Socket.io events are in place and describe the intended shape of the system.
What database and real-time stack does Kandan Core use?
SQLite through Drizzle ORM for storage, with Socket.io handling real-time messaging over WebSockets. Authentication uses JWT with bcrypt, and the API is versioned under /api/v1 with separate routes for auth, channels, messages and users.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/damagelabs-kandan)