Build everything
on one base.

plinto builds, tests, releases and deploys your Java, Kotlin, Go, Rust, Python and TypeScript from one short config per project. Every toolchain is pinned, so the build on your laptop is the build in production.

Request access See how it works Invite-only while in early access.
JavaKotlinGoRustPythonTypeScriptWeb apps
Version groups one exact version of everything, for every project Reviews, builds, releases and deployments one road from commit to production Pinned packages and toolchains JDK · Go · Rust · Node · Python · Gcc · Maven · crates · npm · PyPI
6 languagesone config format for all of them
7 images, 1 binarythe same Rust service on every Linux we tried
0 compilersneeded on the machine that builds
1 clickto put the last revision back in production

Why plinto

Stop gluing five tools together to ship one service.

A build tool per language, lockfiles, CI scripts, an artifact registry, deploy scripts and a wiki page of what runs where. plinto is one system that knows all of it, so it can do the right thing at every step.

today The patchwork

  • ✕
    A different build tool per languageand a different way to declare dependencies in each
  • ✕
    Whatever JDK or compiler the runner hasso "works on my machine" comes back every few weeks
  • ✕
    Every repo upgrades its libraries on its own scheduleand two services end up on two versions of the same library
  • ✕
    CI rebuilds everything, every timeor misses the service that depended on your change
  • ✕
    Deploy scripts and a spreadsheet of what runs whereand a rollback that starts with a search through old jobs

with plinto One base

  • ✓
    One short plinto.conf per projectthe same format for Java, Kotlin, Go, Rust, Python and TypeScript
  • ✓
    Toolchains are packages, pinned like librariesthe JDK, Go, Rust, Node, Python and even the C compiler and linker
  • ✓
    A version group pins one version of everythingall your projects build against the same set, and move together
  • ✓
    Builds take what changed and what depends on iteverything else is reused, and nothing is released until all of it passes
  • ✓
    Pipelines and environments built inapprovals, region-by-region deploys and one-step rollbacks

How it works

Follow one change from a commit to production.

MyService depends on a library, MyLib. Ana changes MyLib. Click through what plinto does next.

BUILD 221 · MAIN PIPELINE · MYSERVICE #21 checks · bake 1 h approval
waitingreadyrunningdonereused

        
You see it in

The model

Three ideas, and everything else follows.

plinto is simple to adopt because there isn't much to learn: projects, packages and version groups.

{ }

Declare, don't script

A plinto.conf names the project, its version line, how it's built and what it needs. There are no tasks to wire up and no plugins to configure in code.

▣

Everything is a package

Java = 25, Rust = 1.98 and the build systems themselves are packages, released and pinned like your own code. Nothing comes from the machine, so nothing differs between machines.

⑂

Version groups work like branches

A group pins one version of every package, and every change makes a new revision. Try a new JDK in a group of its own, then merge it when you're ready.

Your workspace version-group = main@202 MyLib MyService MyWeb main · revision 202 Java 25 → 25.0.4.10.1 Kotlin 2.4.20 Rust 1.98 → 1.98.1 KotlinLib 1.0 (8a1f2e0) Guava 33.7.2-jre MyLib 1.0 (c3d4e5f) MyService 1.0 (a1b2c3d) one pin per package and line Packages toolchains build systems open source templates your releases uses pins
The workspace names a revision, and the revision names every exact version. Java = 25 follows the group's pointer, so moving every project to a new JDK patch is one change.
main 199 200 201 202 MyLib 1.0 Guava 33.7 Rust 1.98.1 jdk-26 1 2 3 4 Java 26 merge from main
A group made from main keeps up with it by merging. Here jdk-26 tries Java 26 on everything while main carries on, and nothing moves until a build or a merge moves it.

Languages

Your whole stack, one config format.

Every language gets a library and a service build system. Services run locally with plinto run and ship as archives or native binaries.

# plinto.conf
{
  name = MyService
  version = 1.0         # plinto numbers each release
  build = JavaService
  packager = GraalVm    # a native binary

  build-dependencies: {
    JavaService = 1.0
    Java = 25           # → 25.0.4.10.1 in main
    GraalVm = 1.0
    OracleGraalVM = 25
  }
  dependencies: {
    MyLib = 1.0         # a project next to it
    Guava = 33          # from Maven Central
  }
  test-dependencies: {
    JUnitJupiter = 6
  }
}
# configuration/JavaService.config: the build system's own settings
main-class = com.example.MyServiceApplication
java.release = 21

JavaLib and JavaService compile with javac, test with JUnit and build a jar. Code lives in src/, tests in tst/, and the build system's settings in configuration/, a file named after it.

Toolchain
Amazon Corretto, for every platform
Ships as
an archive with its own JDK, or a native binary built by GraalVM
Libraries
anything on Maven Central, under names you choose
Templates
a Spring Boot service, ready to run

Platform

Everything from the commit to production, in one place.

plinto isn't just the build tool. It hosts your code or builds it where it already lives, reviews it, builds it, releases it and deploys it, and every part knows what the others did.

⌥

Code

Host a package's repository in plinto, or keep it on GitHub, GitLab, Bitbucket, Codeberg or your own Gitea, Forgejo or GitLab. plinto builds from there, keeps no copy, and hears of pushes through webhooks.

★ MyLib1.0 (e4f5a6b)
★ MyServicegithub.com ↗
✎

Reviews with dry runs

A review can span several packages. Each revision is built against your group, with everything that depends on it, before anyone merges, and a merge lands on your provider's main too.

#12 Greet in the caller's languageapproved
Dry run · MyLib, MyServicepassed
⑂

Version groups

See what each group pins, revision by revision. Compare two revisions, hold a package back, or merge another group's changes in.

main · revision 203from 202
MyLibc3d4e5f → e4f5a6b
▶

Builds

Builds run in parallel on clean workers that have only what your group pins. Retry one package without rerunning the rest.

Build 221 · mainpassed
2 built · 2 reused58 s
⇢

Pipelines

Every new revision goes through your stages: checks, deployments, approvals, bake times, and releases into other groups.

Build ✓ → Beta ✓ → Prodapprove?
Bake 1 h after prodwaits
◎

Environments

What runs where, as a tree per app, with configuration per region, environment and stage. Deploy to your servers over SSH and roll back in one step.

MyService/prod/eurevision 203
MyService/prod/usrevision 202
⧉

Templates

A new app in one go, from a template such as a Spring Boot service: its package, version group, beta environment and pipeline. Templates are packages too, versioned and pinned like everything else.

⚙

Build extensions

Hook your own scripts into a build's phases without writing a plugin. Code generation is coming.

⇩

Open-source imports

Bring in Maven artifacts, Go modules, crates, npm packages and PyPI projects with one command. Each import is checked, released and pinned like your own code.

FAQ

Questions people ask first

Do I have to rewrite my builds?

No, you replace them. Each project gets a short plinto.conf, with its code in src/ and its tests in tst/. Your third-party libraries come in with plinto import, and plinto create starts new projects that build right away.

What does "reproducible" mean here?

Building the same commit with the same version group gives the same file, on any machine. Compilers, linkers and the C library are pinned packages, never the machine's own, and every release records what built it so it can be checked later.

Where do my builds run?

On plinto's build workers. Each task runs in a clean directory with only the packages its group pins. Builds on your laptop use the same packages, so they match.

How are versions decided?

You choose the line, such as version = 1.0. plinto numbers each release in that line when a build passes. A compatible change stays in its line, and workspaces pick it up with plinto update.

Can different teams move at different speeds?

Yes. Each team can work in its own version group, tracking main and merging its changes when the team is ready. A group can also hold a package back while the others move on.

Can my code stay on GitHub or GitLab?

Yes. A package's repository can live on GitHub, GitLab, Bitbucket, Codeberg or your own Gitea, Forgejo or GitLab, private ones included. plinto fetches each commit it needs with your organization's access, keeps no copy, and a push starts what it should through the provider's webhook. Reviews still happen in plinto, and a merge moves your provider's main.

Which IDEs are supported?

IntelliJ IDEA, WebStorm and the other JetBrains IDEs, through the plinto plugin. It opens a workspace, completes plinto.conf, creates new workspaces and builds with plinto itself. Python projects get a .venv that PyCharm and VS Code pick up as well.

Can I sign up today?

plinto is invite-only while in early access. Sign in with Google or GitHub to ask for an invitation; once you're in an organization, everything on this page is yours to use.