Library / SDK
tinylog-org/tinylog avatar
tinylog-org/tinylog

tinylog, a small logging framework that bridges Log4j, JUL and SLF4J

tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android

776 stars86 forksJavaApache-2.0

At a glance

What is it?
tinylog-org/tinylog is a lightweight logging framework for Java, Kotlin, Scala and Android that ships as a set of API and implementation artifacts plus bridges for Log4j 1.2, java.util.logging and SLF4J. It is configured through a properties file rather than XML, and it is written to run on constrained targets.
Who is it for?
Adopt tinylog when you want one logging implementation across several logging APIs in the same application, or when the deployment target is too constrained for a heavier framework, and your team is willing to configure it by hand rather than through XML. Skip it if your organisation has standardised on Logback or Log4j 2 and has no reason to change, since tinylog is a replacement rather than an addition.
Can I use it commercially?
Yes. Apache-2.0 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 2 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 October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The logging call and how small the API surface is

tinylog is described as a lightweight logging framework for Java, Kotlin, Scala and Android, and the example in the README is short enough to memorise:

java
import org.tinylog.Logger;

public class Application {

    public static void main(String[] args) {
        Logger.info("Hello {}!", "world");
    }

}

There is a static Logger with an info call and a placeholder-based message format. No logger factory, no getLogger call, no level checks in the calling code.

The interesting design decision is the artifact split. The repository is a Maven multi-module project and the top level directories show the layering. There is tinylog-api for the public API, tinylog-api-kotlin and tinylog-api-scala for the language-specific variants, tinylog-impl for the implementation, and test-core for the shared test fixtures. On top of that sit the bridges: log4j1.2-api, jul-tinylog, jcl-tinylog, jsl-tinylog, slf4j-tinylog, tinylog-jboss and tinylog-jul.

That set of bridge modules is the feature that distinguishes tinylog from a small logger. It can stand in for Log4j 1.2, for java.util.logging, for the Jakarta Commons Logging facade, for the JBoss Logging facade, for SLF4J and for Jansi-style console formatting, all backed by one implementation and one configuration file.

The consequence for a team with a mixed codebase is that an application with libraries logging through SLF4J, code logging through java.util.logging, and its own code using tinylog directly can end up with a single configuration and a single log file, instead of several appenders fighting over the same output.

Configuration through a properties file

tinylog is configured with a tinylog.properties file, and the README example shows two writers with different formats and different destinations.

properties
level            = INFO

writer1          = console
writer1.format   = {date: HH:mm:ss.SSS} {class}.{method}() {level}: {message}

writer2          = rolling file
writer2.file     = logs/{date: yyyy-MM-dd}/log_{count}.txt
writer2.policies = startup, daily: 03:00
writer2.format   = {date: HH:mm:ss} [{thread}] {level}: {message}

The shape is worth reading closely. A top-level level setting sets the threshold, and each writer is named and then given a type. The console writer needs nothing else. The rolling file writer needs a file pattern, a set of policies and a format.

The file pattern uses the same brace syntax as the format string, and it includes a date placeholder plus a count placeholder, so log files land in a dated directory with a numbered filename. The policies line is a comma-separated list, and the daily policy takes a time, so this example rolls at 03:00 and also on startup.

The format strings use a placeholder language of their own: date with a Java-style pattern, class and method, level, message and thread. The console format here includes class and method, which is the expensive field for the JVM to produce, while the file format uses thread instead.

Compared with Logback or Log4j 2, this is a much smaller configuration language and it is a plain properties file. There is no XML to parse, no plugins to load, and the runtime cost of a format is a string substitution rather than a layout chain. The trade-off is that the expressiveness is lower, and the reference to tinylog.org/v2/ for the full manual is where the detail lives.

The bridge modules and how migration works

The bridge directories at the repository top level are the practical part of adopting tinylog in an existing application.

Each bridge is a separate artifact that translates calls from one logging API into tinylog's own. The log4j1.2-api module provides the Log4j 1.2 API surface backed by tinylog, which matters because Log4j 1.2 has been out of mainstream support for years but a lot of libraries still call it. The slf4j-tinylog module does the same for SLF4J, the facade most Java projects use, and jul-tinylog covers java.util.logging. There are also jcl-tinylog for Commons Logging, jsl-tinylog for JBoss Logging, and tinylog-jboss and tinylog-jul modules on the tinylog side of the same arrangement.

The migration path these modules create is the interesting part. You can replace the log4j-1.2-api and slf4j-api artifacts on the classpath with the tinylog equivalents, delete the old configuration, and the calling code does not change at all. Every log statement that previously went through a different framework now lands in the writers you configured once.

That is a genuinely different approach from the usual migration, where you switch a binding and keep a familiar configuration format. Here the configuration format changes too, which is more work up front and less ongoing, since one file replaces several.

The Kotlin and Scala API modules exist for the same reason the bridges do, to let code in those languages use a facade that fits their conventions while the implementation stays shared. For Scala that means an API that suits its expression style rather than the static Java-style calls.

Target platforms, releases and licence

The topic list on the repository names the target platforms: Java, Kotlin, Scala and Android, with Android called out separately. That is the reason for the lightweight framing, since a framework that has to run inside an Android application or on a small device cannot afford the class loading and configuration machinery of Logback.

The project is a Maven build, so consumers get artifacts from Maven Central under the org.tinylog group, and the README links the tinylog-impl artifact as the representative one. The build is driven by a build.yaml workflow with a codecov badge for coverage, and the repository carries a .codecov.yml configuration and a benchmarks directory, so performance is tracked rather than assumed.

The release pattern is steady. Version 2.8.1 shipped on 2026-10-05, 2.8.0 on 2026-09-07, and a 2.8.0 milestone build in August, which is the pattern of a maintained project with an occasional larger feature release. The default branch is v2.8, so the branch name tracks the current minor series. The last push was on 2026-10-19.

Licensing is Apache License 2.0, copyright 2016 to 2026 Martin Winandy, which is the same single-maintainer model the project has had throughout. That is worth noting for procurement: one person owns the copyright and the maintenance, and the answer to a support question is a GitHub issue.

The README points to contributing.md for the build and contribution process, and to release.md for the release procedure, both of which live in the repository.

How tinylog compares with SLF4J plus Logback and with Log4j 2

The default answer in the Java ecosystem is SLF4J as the facade and Logback as the implementation, or SLF4J with Log4j 2 behind it. The difference in approach against that setup is mostly about configuration and footprint rather than capability.

Logback gives you XML configuration, conditional processing, filters, appenders with their own retry and rollover policies, and a rich ecosystem around it. tinylog gives you a properties file, a smaller set of writers, and a much smaller runtime. For a server-side application with complex routing requirements, Logback is the more capable tool and nothing about tinylog changes that.

Where tinylog pulls ahead is in constrained environments and in mixed-API codebases. An Android application or an embedded JVM has no room for an XML parser and a plugin loader at startup, and a properties file with a fixed set of writers is a reasonable answer. And the bridge modules mean you do not have to standardise on one logging call across a large legacy codebase in order to standardise on one configuration.

The cost of tinylog is that the migration touches more than a binding swap. You learn a new configuration language with its own placeholder syntax, you lose the extension points you might have used, and if you later need something the writer model does not cover, you are writing a custom writer rather than composing an existing appender chain.

One more alternative is worth naming for context: log4j2 with its async loggers and disruptor ring buffer for high throughput. tinylog does not compete there, and a service with genuinely high log volume is not the case tinylog is aimed at.

Editorial conclusion

Adopt tinylog when you want one logging implementation across several logging APIs in the same application, or when the deployment target is too constrained for a heavier framework, and your team is willing to configure it by hand rather than through XML. Skip it if your organisation has standardised on Logback or Log4j 2 and has no reason to change, since tinylog is a replacement rather than an addition. Verify first by running the example on the classpath and confirming that the writers you need, such as console and rolling file, appear in the tinylog.properties file you write.

Frequently asked questions

What does tinylog do and which languages does it support?

tinylog is a lightweight logging framework for Java, Kotlin, Scala and Android. The API is a static Logger class with placeholder-based calls, and the repository contains separate API modules for Java, Kotlin and Scala plus a tinylog-impl implementation module.

How do I configure tinylog?

With a tinylog.properties file. The README example sets a top-level level, then defines writers by name and type, for example writer1 = console and writer2 = rolling file, each with its own format string, and the file writer taking a file pattern and a list of policies such as startup and daily: 03:00.

Can tinylog replace Log4j 1.2 or SLF4J in an existing project?

Yes. The repository ships bridge modules including log4j1.2-api, slf4j-tinylog, jul-tinylog, jcl-tinylog and jsl-tinylog, each of which presents another logging API while routing calls to tinylog, so calling code stays unchanged while the configuration is unified.

What is the latest tinylog release and what licence is it under?

Version 2.8.1 was released on 2026-10-05 after 2.8.0 in September 2026. The project is licensed under the Apache License, Version 2.0, with copyright held by Martin Winandy from 2016 to 2026.

Is tinylog suitable for Android applications?

Android is one of the target platforms the repository lists, and the lightweight design is the reason: a properties file and a fixed set of writers avoid the XML parsing and plugin loading that heavier logging frameworks add at startup.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. tinylog-org/tinylog on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tinylog-org-tinylog.svg)](https://hysenlabs.com/projects/tinylog-org-tinylog)