How to build an inlang app

This guide gives you an introduction on how to build your own inlang app.

Felix Häberle

#Building an Inlang App: A Comprehensive Guide

Inlang is a versatile globalization ecosystem that empowers developers to seamlessly integrate language translation capabilities into their applications. This comprehensive guide will walk you through the process of building a general Inlang app with the @inlang/sdk.

We'll cover initializing a project from a repo, creating and updating messages, and working with lint rules.

#1. Open Repository

All Inlang projects live in a repo, so first we use the lix client to open the repo.

We can use node:fs for repos which are already in the filesytem. E.g. This example uses the lix client to find the repo root starting from the current working directory, and then opens the repo there.

import fs from "node:fs/promises"
import { openRepository, findRepoRoot } from "@lix-js/client"

const repoRoot = await findRepoRoot({ nodeishFs: fs, process.cwd() })

const repo = await openRepository(repoRoot, {
    nodeishFs: fs,

Or, use createNodeishMemoryFs to open a GitHub repo from a browser:

import { createNodeishMemoryFs } from "@lix-js/fs"
import { openRepository } from "@lix-js/client"

const repoURL = "https://github.com/inlang/ci-test-repo"

const repo = await openRepository(repoURL, {
    nodeishFs: createNodeishMemoryFs(),

#2. Load Project

The next step is to initialize a project from the repo, using the Inlang SDK. This sets the foundation for your Inlang powered application.

Since there may be multiple projects in a repo, a projectPath needs to be specified. The default projectPath is /project.inlang.

import { loadProject } from "@inlang/sdk";

const projectPath = "/project.inlang";

const inlang = loadProject({

#2. Create and update Messages

With the project initialized, creating and updating messages is straightforward. Use the inlang.query.messages.create function to create a message and inlang.query.messages.update to update it.

There are also a few other query/mutation functions you can use.

#Creating Messages

const messageData = /* your message data */;
inlang.query.messages.create({ data: messageData });

#Updating Messages

const updatedMessageData = /* your updated message data */;
inlang.query.messages.update({ args: updatedMessageData });

These functions internally handle the loading and saving of messages according to your defined plugin (e.g., JSON, i18next, Inlang message format).

#3. Working with Lint Rules

Lint rules are crucial for maintaining code quality and consistency. In your Inlang app, you can leverage lint rules to ensure that your localization messages adhere to specific standards. For example, let's explore working with the snakeCaseId lint rule.

This lint rule checks whether your message id's are in a snake case format or not.

To fetch lint reports for a message, use the async lintReports.get() function.

const reports = await inlang.query.lintReports.get({ where: { messageId: message.id } })
/* do something with reports */

#Publishing your app

If you are ready and want to release what you have built, please publish your app on our Marketplace – where you can also sell apps in the future.


Now it's your turn! We can't wait what you wil build with the inlang SDK. The possibilities are near endless – like a Chrome extension, a Sketch plugin, a Translation Analytics tool? Happy coding!

Edit on GitHub