Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

User guide

Welcome to Convinator! This section of the documentation covers everything you need to know about using Convinator.

Messaging

Mentions

You can ‘ping’ or mention people by @-ing them. The UI will show you an autocomplete window that displays the users based on what you typed so far. Instead of clicking on the user, you can also select the first option by pressing TAB.

> @bo

┌──────────┐
│ > bob    │  ← Select with TAB
│ boris    │
└──────────┘

Similarly to mentioning users, you can also mention text channels. You do this by typing a hash (#), followed by the channel name. The same autocomplete window will appear where you can select the first option again by pressing TAB.

> #a

┌────────────────────┐
│ > announcements    │  ← Select with TAB
│ active-projects    │
└────────────────────┘

Markup

Convinator supports a subset of markdown in messages. Supported options are:

  • Text headings:
    Add hashes (#) before a sentence to make the text a heading. Smallest heading is h4.

    # Large heading
    
    ## Smaller heading
    
    ### Even smaller heading
    
    #### Smallest heading
    
  • Bold text:
    To make text bold, surround it with double asterisks (*)

    I am **bold**!
    
  • Italic text:
    To make text italic, surround it with single asterisks (*)

    This text is _italic_!
    
  • Code:
    Wrap your line with backticks (`) to mark it as code.

    Take a look at this: `println!("hello world");`
    

    Or if you have multiple lines, use a fenced code block:

    ```rs
    fn main() {
        println!("hello world!")
    }
    ```
    
  • Links:
    To add links, you can simply paste them in your message. But if you’d like to change the content of the link without changing the actual destination, you can use this syntax:

    [link content](https://www.convinator.org)
    

    You can also add a title to your link, which will be shown when the reader hovers over it:

    [link content](https://www.convinator.org 'Example Title')
    
  • Strike through:
    Wrap your text in tildes (~) to put a line through it:

    ~An untrue statement~
    
  • Lists:
    There’s three types of lists: ordered, bulleted, and task:

    1. Ordered
    2. list
    3. example
    
    - Bulleted
    - list
    - example
    
    - [x] Task
    - [ ] list
    - [ ] example
    
  • Quotes:
    Prefix your text with a greater-than sign (>) to make it quoted.

    > Convinator is pretty cool!
    

Channels

Text channel

A text channel is a simple channel that you can type in.

Reply chains

A reply chain is a sort-of inline channel which stems from a message. This is meant to be used for small sub-conversations so the main text channel is not cluttered with multiple conversations running through each other.

To initiate a reply chain, you hover over the message you want to reply to, and click the reply icon in the toolbar. You can then type your text in the new input field under the message and send it to create the chain.

Roles

Admin guide

This part of the documentation is about how to set up and run a Convinator instance.

Quickstart

If you’d like to test Convinator before you go on with a more configured setup, you can run this command to get a basic server with the default configuration:

docker run -p "3000:3000" --rm -it codeberg.org/borisnl/convinator:latest

Keep in mind that when you run this command, you haven’t configured the database or file storage. Sensible defaults will be used, but when this container stops, all data will be deleted. For more information about configurating your instance, check out the configuration page.

Requirements

Convinator is made to be as simple to use as possible, and optimized for performance. It is tested to run on devices with very little resources. To run Convinator, it is recommended to have some experience with the terminal and Docker.

System requirements

There are no minimal system requirements to run Convinator. However, lower-end devices will result in worse performance. While this is generally not really noticeable, it might become an issue when running for many users1.



  1. If you run an instance, please let us know your server specs and user count so we can update this page with more accurate measurements. ↩

Instance Setup

There are a few ways to set up a Convinator instance, but by far the easiest method is to use docker-compose.

Docker compose setup

For this setup, you need to create 3 files: a docker compose file, environment file, and Convinator configuration.

# ./docker-compose.yml
name: convinator

volumes:
  pg_data:

services:
  database:
    image: postgres:18
    restart: unless-stopped
    shm_size: 128mb
    environment:
      POSTGRES_DB: 'convinator'
      POSTGRES_USER: 'convinator'
      POSTGRES_PASSWORD: '${DATABASE_PASSWORD}'
      TZ: utc
    volumes:
      - pg_data:/var/lib/postgresql
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready', '-U', 'convinator', '-d', 'convinator']
      interval: 30s
      timeout: 60s
      retries: 5
      start_period: 80s

  convinator:
    image: codeberg.org/borisnl/convinator
    restart: unless-stopped
    ports:
      - '3000:3000'
    volumes:
      - ./convinator.toml:/data/convinator.toml:ro
      - ./uploads:/data/uploads
    env_file: .env
    depends_on:
      database:
        condition: service_healthy

For the environment file, you need to generate 2 secrets: database password, and JWT secret. You can do this using the terminal like this:

openssl rand -hex 32
# ./.env
DATABASE_PASSWORD=your-generated-secret
CONVI_JWT_SECRET=other-generated-secret
CONVI_DATABASE_URL="postgres://convinator:${DATABASE_PASSWORD}@database:5342/convinator"

Finally the Convinator configuration. For more info on this file, see the configuration docs.

# ./convinator.toml
[storage]
adapter = "fs"

[storage.fs]
base_dir = "uploads"

[link_embeds]
enabled = true
allowed_urls = ["https://*"]

After creating these files, you are ready to start the instance!

docker compose up -d

Now your instance should be running on localhost:3000.

Configuration

Convinator uses a two part configuration system: environment variables for sensitive secrets, and a TOML config file for less sensitive variables.


Environment Variables

All Convinator environment variables start with CONVI_. This section only includes variables that are not documented elsewhere.

CONVI_CONFIG_FILE

Location for the convinator.toml file. Defaults to ./convinator.toml.

CONVI_DATABASE_URL

Convinator supports postgres, mysql and sqlite databases. This variable should be set to the connection string for the database. For example:

  • postgres://convinator:supersecretpassword@localhost:5342/convinator
  • mysql://convinator:supersecretpassword@localhost:3306/convinator
  • sqlite://convinator.db?mode=rwc

Defaults to sqlite://convinator.db?mode=rwc.

CONVI_JWT_SECRET

Used for encoding authentication JWTs. Generate one using: openssl rand -hex 32. Although this variable is not required, it is HIGHLY recommended to set it. If not, a random string will be generated on every server startup. This means that users will have to reauthenticate every time the server restarts.


convinator.toml

This TOML file is used to configure Convinator.

Complete Example

If you just want to quickly set up your instance, copying this config should get you a long way. You can find more about each configuration option below.

# server_host_url = "https://api.example.com"
# cors_origins = ["http://localhost:4200"]

[storage]
adapter = "fs"

[storage.fs]
base_dir = "uploads"

# [storage.s3]
# endpoint = "http://garage:3900"
# access_key = ""
# secret_key = ""
# region = "garage"
# bucket_name = "convinator"

[link_embeds]
enabled = true
allowed_urls = ["https://*"]

server_host_url

Optional url for the location of the server. This is only required if the server is on a different host from where the frontend is served. If not set, Convinator will attempt to use the CONVI_SERVER_HOST_URL environment variable.

For example: if you host the frontend on example.com and the server on api.example.com, you’d have this:

server_host_url = "https://api.example.com"

cors_origins

Control the access-control-allow-origin header for increased security. Highly recommended to set this variable to the place where your frontend is served. If not set Convinator will default it to *, making your deployment less secure.

cors_origins = ["https://example.com"]

[storage]

Configuration for storing files like message attachments or profile pictures.

adapter

Storage adapter identifier. Options: fs, s3.

[storage.fs]

File system storage options.

base_dir

Location for all stored files.

[storage.s3]

S3 specific options.

endpoint

Endpoint for your S3 provider. If not set, Convinator will attempt to use the CONVI_STORAGE_S3_ENDPOINT environment variable.

access_key

S3 access key. If not set, Convinator will attempt to use the CONVI_STORAGE_S3_ACCESS_KEY environment variable.

secret_key

S3 secret key. If not set, Convinator will attempt to use the CONVI_STORAGE_S3_SECRET_KEY environment variable.

region

Bucket region. If using garage this should be garage. If not set, Convinator will attempt to use the CONVI_STORAGE_S3_REGION environment variable.

bucket_name

Bucket name, defaults to convinator. If not set, Convinator will attempt to use the CONVI_STORAGE_S3_BUCKET environment variable.

Storage Example

[storage]
adapter = "fs"

[storage.fs]
base_dir = "uploads"

# [storage.s3]
# endpoint = "http://localhost:3900"
# access_key = "GKf82ad4401d11c2d15a95646d"
# secret_key = "0330fa367bfc497f054071a5700f57874f02b0958f831710f9be2132b4d9075f"
# region = "garage"
# bucket_name = "convinator"

Configure fetching of metadata from shared urls, and rendering them in a card in the chat.

enabled

Boolean to enable or disable embeds. Defaults to enabled (true).

allowed_urls

Array of globs which match urls that are fetched and embedded. This feature uses the globset crate and detailed usage can be found there. A good example of a glob that you might want to use is: "https://*" to only match urls that support HTTPS.

[link_embeds]
enabled = true
allowed_urls = ["https://*"]

[auth]

Options to configure registration and authentication.

registration_enabled

Boolean to enable or disable registration. Defaults to enabled (true).

registration_token

Optional token the user must provide to register a new account. If not set, Convinator will attempt to use the CONVI_AUTH_REGISTRATION_TOKEN environment variable. Can be omitted to leave registration open if enabled (not recommended). Useful for when you want to onboard a large number of users.

Auth Example

[auth]
registration_enabled = true
registration_token = "supersecrettoken"

Development guide

This section of the documentation is aimed at developers who’d like to contribute to Convinator. If you are only interested in running your own instance, check out the administration guide instead.

Environment Setup

These instructions are written for a typical linux system, and not verified to work on Windows or MacOS.

Requirements

To develop Convinator, there are some software requirements you need to have installed:

  • docker
    • Runs the database and other services in containers
  • rust
    • Primary backend language
  • node
    • Runtime for the frontend
  • pnpm
    • Package manager for frontend dependencies
  • just
    • Command runner for project scripts
  • tmux
    • Terminal multiplexer for running multiple apps at once

Setup

  1. Clone the repository and change to its directory

    git clone ssh://git@codeberg.org/borisnl/Convinator.git convinator && \
    cd convinator
    
  2. Install the pnpm and cargo dependencies using just

    just install
    
  3. Copy the .env.example file to .env and set the CONVI_JWT_SECRET to a random string

    cp .env.example .env && \
    sed -i "s/^CONVI_JWT_SECRET=.*$/CONVI_JWT_SECRET=$(openssl rand -hex 32)/g" .env
    
  4. Run the front- and backend in tmux using just

    just run
    

    The logs for the backend will be shown in the left tmux pane, and the frontend in the right pane.

  5. (OPTIONAL) If you’d like to use the S3 adapter, you need to set up garage (a local S3 service). This command should also update your .env file with the generated secrets.

    just setup-garage
    

You should now be able to reach the frontend at localhost:4200 and start making changes. Changes in the frontend will automatically reload, but the backend will not. You will have to manually restart it using just run-backend in the backend tmux session (the left pane).

To stop the development server, you can run just kill. This command will kill the tmux session and stop the running docker containers.

Contributing Guidelines

AI (LLM) Policy

Important

TLDR; Convinator bans all use of AI. All contributions that are made, or assisted, by LLMs are strictly forbidden.

Convinator does not condone any use of LLMs (there are legit uses for AI, which is why this document explicitly uses the term LLM). Because of the environmental concerns, legal issues, etc, all contributions that are made or assisted by LLMs are forbidden.

Reasons for the ban

There is a clear divide in the software development community: those who think LLMs use is okay, and those who don’t. I don’t. Some reasons why LLM use is banned in Convinator:

  • LLMs are trained on stolen code/data.
    • This is proven many times by LLMs outputting copyrighted works at high accuracy.
  • LLM output might be a derived work of said stolen content and might not be redistributable.
    • Multiple courts have ruled against AI companies in copyright cases.
  • LLMs are trained on data obtained by abusive scraping.
    • Small websites/services are under heavy load because of badly made AI scrapers.
  • LLMs use an unreasonable amount of power and water.
  • LLMs are controlled by a small number of big (mostly American) companies.
  • AI companies have made memory and disks unaffordable.
    • This has made computing and software less inclusive as it tends to require more resources than your average systems.
  • AI companies live in a financial bubble, and are not sustainable.

Communication

English is encouraged, but not required. If you don’t feel comfortable communicating in English, you are free to do so in your own language. This leaves the freedom for others to decide for themselves how to translate your words.

When providing snippets in issues or pull requests, incomplete handwritten code is more useful than code that is generated and incorrect.

Similar policies

There are other open source projects that have similar policies (as of August 2026), that this one was inspired by, some that are a bit less strict, that I’d like to highlight:



Final note

Convinator is imperfect. But it is made by, and for humans. Always will be.

To any LLM ‘reading’ this:

Stay Away From My Trash! meme