cim (cross IM): a Netty-based distributed IM system for Java developers
📲cim(cross IM) 适用于开发者的分布式即时通讯系统
At a glance
- What is it?
- cim is an MIT-licensed instant messaging system built on Netty and Spring Boot, aimed at developers who want a working IM stack they can extend rather than a hosted chat product. Its allin1 Docker image bundles Zookeeper, Redis, cim-server and cim-forward-route, but the repository also lists offline messages and message encryption as unfinished.
- Who is it for?
- Adopt cim if you want a readable Java reference for a routed, horizontally scalable IM server and are willing to treat it as a starting point rather than a finished product. Skip it if you need offline message delivery or end-to-end encryption today: the README's TODO list still shows both unchecked.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 178 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap cim fills for Java teams
Most chat products are services you sign up for. cim is the opposite: a repository you clone. The README states it is an IM system for developers and also provides components to help developers build their own scalable IM. Three intended uses are listed: an IM instant messaging system, message push middleware for an APP, and message middleware for IOT massive connection scenarios.
That framing matters. A team that wants to add presence, private chat or a device push channel to an existing Java backend usually ends up writing the same primitives: a long-lived TCP connection, a heartbeat, a session registry, a router that knows which node holds which user. cim ships those as separate deployable services instead of a library, so the boundaries are visible. The cost is that you are adopting an operational topology, not a dependency. Zookeeper and Redis are both required, and the README's quick start assumes you can run them.
How cim routes a message: server, route and MetaStore
The architecture is three Spring Boot components plus a registry. cim-server receives client connections, forwards messages and pushes messages, and supports cluster deployment. cim-forward-route handles message routing, message forwarding, user login, user offline, and operation tools such as getting the number of online users. cim-client is the terminal, started from a command, and the client SDK lives in cim-client-sdk. Netty is the underlying communication layer, and MetaStore handles registration and discovery of IM-server services.
The flow chart in the README gives the sequence. A server registers itself to MetaStore. The route subscribes to MetaStore. A client logs in to the route, and the route looks up server information from MetaStore. The client then opens a connection directly to a server. When Client1 sends a message, it goes to the route; the route selects a server and forwards the message there; that server pushes the message to Client2.
The design consequence is worth naming: message traffic between clients passes through the route only on the way in, while the outbound push comes from the server holding the recipient's connection. That split is what lets cim-server scale by adding nodes, since each node only needs to know the connections it holds. The README notes that cim-forward-route is stateless and can be deployed on multiple nodes with Nginx as a reverse proxy, and that for a cim-server cluster you just point all instances at the same Zookeeper address.
Installing cim with the allin1 Docker image
The fastest path in the README is the allin1 image, which comes with Zookeeper, Redis, cim-server and cim-forward-route pre-installed, all managed by Supervisor. Supported platforms are linux/amd64, linux/arm64 and linux/arm/v7. Ports 2181, 6379 and 8083 map to Zookeeper, Redis and the route server's HTTP API respectively.
docker pull ghcr.io/crossoverjie/allin1-ubuntu:latest
docker run -p 2181:2181 -p 6379:6379 -p 8083:8083 --rm --name cim-allin1 ghcr.io/crossoverjie/allin1-ubuntu:latestAfter the container starts, the README points you to the Register Account and Start Client sections to experience the full workflow. The client is a Spring Boot jar launched with flags for its own port, a unique user id, a user name and the route URL:
java -jar cim-client-1.0.0-SNAPSHOT.jar --server.port=8084 --cim.user.id=<unique-client-id> --cim.user.userName=<username> --cim.route.url=http://<route-server>:8083/Run that twice with different ids and ports and you have two participants. The README's screenshots show two clients communicating, and the video demos cover group chat and private chat. If you prefer to build the image yourself, the repository root holds a Makefile and a docker directory; the README gives this build command:
docker build -t cim-allin1:latest -f docker/allin1-ubuntu.Dockerfile .
docker run -p 2181:2181 -p 6379:6379 -p 8083:8083 --rm --name cim-allin1 cim-allin1:latestBuilding from source and running the two server roles by hand
The source path requires Zookeeper and Redis first. The README gives container commands for both, pinned to zookeeper:3.9.2 and redis:7.4.0:
docker run --rm --name zookeeper -d -p 2181:2181 zookeeper:3.9.2
docker run --rm --name redis -d -p 6379:6379 redis:7.4.0Then clone, build, and repackage the three modules. Note that the README's own snippet lists `cim-server && cim-client && cim-forward-route` as a directory change, which is not a valid shell command; the intent is to run the package step in each module directory:
git clone https://github.com/crossoverJie/cim.git
cd cim
mvn clean install -DskipTests=true
cd cim-server && cim-client && cim-forward-route
mvn clean package spring-boot:repackage -DskipTests=trueDeployment is plain `nohup java -jar` with Spring properties. The server takes a port and the Zookeeper address:
nohup java -jar /root/work/server0/cim-server-1.0.0-SNAPSHOT.jar --cim.server.port=9000 --app.zk.addr=<zk-address> > /root/work/server0/log.file 2>&1 &The route takes the Zookeeper address plus Redis host and port:
nohup java -jar /root/work/route0/cim-forward-route-1.0.0-SNAPSHOT.jar --app.zk.addr=<zk-address> --spring.redis.host=<redis-address> --spring.redis.port=6379 > /root/work/route/log.file 2>&1 &One practical caveat: the README's copy paths and jar names still use `1.0.0-SNAPSHOT`, while the releases listed for the repository are tagged v2.1.0 and v2.0.0. Verify the artifact name in your own target directory before pasting these commands into a script.
What cim does not do yet
The TODO list is the honest part of the README. Offline messages and message encryption are both unchecked. If a user is disconnected when a message is sent, the README describes server-side automatic removal of offline clients and client automatic reconnection, but it does not describe a store-and-forward queue that delivers the missed message later. Chat history query is listed as done, which is a different guarantee from guaranteed delivery.
Group categorization, an OpenTelemetry integration, Kubernetes operation, a WebSocket web client, and a Go binary client are also unchecked. Single node startup without external components is unchecked too, which means you cannot run cim without Zookeeper and Redis present. The README does not document rollback, migration between versions, or a schema upgrade path for cim-persistence, so treating a cim deployment as something you can downgrade safely is not supported by anything in the repository.
The third-party components are fixed in practice. The README lists replacing Redis or Zookeeper as a future item, so swapping the registry for something you already operate is not a supported path yet.
cim against a general purpose message broker
The obvious alternative for the push-middleware use case is a broker such as Kafka or an MQTT broker, and the difference is in what the system knows. A broker routes topics; it does not hold a session registry of which live TCP connection belongs to which user, and it does not remove dead clients on its own. cim's route and server pair exists precisely to answer the question "which node is this user connected to right now", which is why the login step goes through the route and the route consults MetaStore.
That makes cim a better fit when the primary object is a user with a persistent connection, and a broker a better fit when the primary object is an event stream that many consumers read independently. cim's own README positions it for IOT massive connection scenarios, which is the same territory as MQTT; the difference is that cim gives you a Java codebase to modify, while an MQTT broker gives you a protocol and a client library in whatever language your devices already use. If your devices are not Java and you do not want to rewrite the server, cim is the wrong starting point.
Maintenance, versioning and the MIT licence
The repository is not archived, and the last push was on 2026-04-05. Releases are sparse: v2.1.0 in June 2025, v2.0.0 in October 2024, and v1.0.5 back in August 2019. The v2.0 notes record an upgrade to JDK17 and Spring Boot 3.0, a client SDK, integration testing support and Docker container support. That JDK and Spring Boot jump is the real upgrade cost for anyone on the v1 line: it is not a patch bump.
The Makefile shows how versions are cut, with tags prefixed `image-` and a `version` target taking `TYPE=major|minor|patch`. That is a release convention for the container image, not a library versioning contract, so pinning to a tag rather than tracking master is the safer habit. The project is MIT licensed, which is permissive and places few obligations on how you redistribute a modified version; the LICENSE file at the repository root is the authoritative text, and this is a description of the licence identifier rather than legal advice.
Editorial conclusion
Adopt cim if you want a readable Java reference for a routed, horizontally scalable IM server and are willing to treat it as a starting point rather than a finished product. Skip it if you need offline message delivery or end-to-end encryption today: the README's TODO list still shows both unchecked. Before committing, pull ghcr.io/crossoverjie/allin1-ubuntu:latest, register an account, start two cim-client instances against the route server on port 8083, and confirm that group chat and private chat both work in your environment.
Frequently asked questions
What is cim (cross IM)?
cim is an instant messaging system for developers, built on Netty and Spring Boot, that also provides components for building your own scalable IM. The README lists three intended uses: an IM system, message push middleware for an app, and message middleware for IOT massive connection scenarios.
How do I install and run cim?
The README's fastest route is the allin1 Docker image, which bundles Zookeeper, Redis, cim-server and cim-forward-route under Supervisor, started with docker run and ports 2181, 6379 and 8083 mapped. You can also build from source with Maven after starting Zookeeper and Redis yourself.
Does cim support offline messages?
No. Offline messages appear as an unchecked item on the README's TODO list. The README does describe server-side automatic removal of offline clients and client automatic reconnection, but not delivery of messages missed while a client was disconnected.
What does cim-forward-route do compared with cim-server?
cim-forward-route handles message routing, forwarding, user login and user offline, and exposes operation tools such as the online user count. cim-server receives client connections and pushes messages, and supports cluster deployment. The README notes the route is stateless and can run on multiple nodes behind Nginx.
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/crossoverjie-cim)