Shapeless: generic programming for Scala, and what it costs to adopt
Generic programming for Scala
At a glance
- What is it?
- Shapeless is a type class and dependent type based generic programming library for Scala, used where arities need abstracting over and boilerplate needs scrapping. It is powerful, thinly documented, and still on the 2.x line.
- Who is it for?
- Adopt shapeless if you are on Scala 2.11, 2.12 or 2.13 and you have a concrete arity or boilerplate problem that ordinary Scala generics cannot express. Do not adopt it for Scala 3, and do not adopt it because a blog post made heterogeneous lists look fun.
- 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 9 days ago.
- What is it written in?
- Mainly Scala, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The arity problem shapeless exists to solve
Ordinary Scala generics abstract over types, not over how many of them there are. Write a case class with seven fields and you cannot hand it to a method that only knows how to walk a two-field product. The README frames the audience directly: the library is "being used widely in production systems wherever there are arities to be abstracted over and boilerplate to be scrapped." That is the whole pitch. If your codebase has hand-written encoders for every case class, or a copy-pasted fold for tuples of every size, shapeless is aimed at you. If your code has one product type with four fields and it never changes, shapeless is a large dependency bought to solve a problem you do not have.
The library began as talks given in 2011 on implementing scrap your boilerplate and higher rank polymorphism in Scala, and the README is candid that it evolved "from being a resolutely experimental project" into something still "testing the limits of what's possible in Scala." That sentence describes both its value and its cost. It is a library whose selling point is that it goes further than the language normally allows, which also means its failure modes live in the compiler.
HList, Coproduct and the type class machinery underneath
The mechanism is type classes plus dependent types. The README's own REPL transcript is the clearest illustration of the data structure at the centre of the library: entering 23 :: "foo" :: true :: HNil yields a value typed Int :: String :: Boolean :: HNil. That is a heterogeneous list, a value whose static type records the type of every element and the length of the sequence. Because the type carries that information, type classes can be resolved at compile time by walking the structure, which is how encoders, decoders, folds and generic traversals get derived rather than written by hand.
The dual construction is the coproduct, the sum-type counterpart used for sealed trait hierarchies. Around both sits machinery for arity abstraction, and the repository layout reflects the split: a core/ module, a coreTestMacros/ module, a plugin/ module and an examples/ directory. Derivation happens in the compiler through implicit resolution, which is why the library ships a compiler plugin at all. The practical consequence is that the interesting failures are compile-time failures, and they arrive as implicit-not-found errors whose messages describe a type-level search rather than your business logic. Reading those errors is a skill, and the README does not teach it.
Getting a shapeless REPL in one command
The README's fastest path needs nothing but an installed JDK. The provided try-shapeless script downloads coursier, uses it to fetch the Ammonite REPL and the latest shapeless, and drops you at a prompt. The documented invocation is a single curl piped to bash. Run it and you should see the Ammonite banner, a Scala version line, and an @ prompt ready for input:
curl -s https://raw.githubusercontent.com/milessabin/shapeless/main/scripts/try-shapeless.sh | bashAt that prompt, the README's own example builds a heterogeneous list and shows the inferred type. Type it in and the REPL echoes back both the value and its type, which is the moment the library's premise becomes concrete:
23 :: "foo" :: true :: HNil
res0: Int :: String :: Boolean :: HNil = 23 :: "foo" :: true :: HNilBecause this route uses coursier and Ammonite, nothing is added to your build. That is deliberate: it lets you evaluate the library before committing a dependency to a project. When you do want it in a build, the README's SBT section points at adding the Sonatype repositories so that releases and snapshots resolve:
resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots")
)Artefacts are published to the Sonatype OSS Repository Hosting service and synced to Maven Central, under the com.chuusai group. The README names the Maven Central badge for com.chuusai:shapeless_2.13, so the artefact suffix tracks the Scala version you build against.
Where shapeless is the wrong tool
The README states plainly that builds are available for Scala 2.11.x, 2.12.x and 2.13.x. Scala 3 is not in that list. If your project has moved to Scala 3, shapeless is not a candidate, and the Scala 3 compiler's own match types, inline methods and given/using syntax cover a good deal of the derivation ground shapeless was built to cover on Scala 2. That is a boundary, not a defect, but it decides the question for a growing share of teams.
The second limitation is documentation. The README says the feature overview for shapeless-2.0.0 is "a very incomplete introduction," and then says directly: "We're not satisfied with the current state of the documentation and would love help in improving it." A library that asks its users to help write the docs is telling you something about the onboarding curve. The README points elsewhere for learning material, including The Type Astronaut's Guide to Shapeless, the release notes, and the migration guides from 1.2.4 to 2.0.0 and from 2.0.0 to 2.1.0. Note that the migration guides stop at 2.1.0; the README does not document a migration path from 2.1.0 to the 2.3.x line, so an upgrade from an old 2.1 codebase has no single document to follow.
The third is the compiler plugin. A build that depends on a plugin is tied to compiler versions in a way an ordinary library is not, and the README does not describe plugin compatibility guarantees across Scala releases. Treat that as an unverified risk to check against your own compiler version rather than something the project promises to handle.
How shapeless differs from plain Scala derivation
The realistic alternative is not another library but writing the derivation yourself with the Scala 2 features you already have: implicit defs, context bounds, and macros. That approach has a real advantage. The code stays legible to anyone on the team, the compiler errors point at your own implicits, and there is no third-party plugin in the build. It has an equally real cost: you reimplement arity abstraction every time you meet a new shape, and the recursion over product and sum types is exactly the part that is tedious and easy to get subtly wrong.
Shapeless's difference in approach is that the type-level structure is a first-class value, the HList and the coproduct, rather than something you simulate with nested tuples and overloads. A derived type class instance is then produced by resolving implicits against that structure, so one definition covers products of any arity. The trade is knowledge: you buy generality with a type-level vocabulary your team has to learn, and with error messages that describe that vocabulary rather than your domain.
A second alternative, for teams that need serialization specifically, is a code-generating macro library, which produces the encoder source at compile time and keeps the generated code inspectable. Shapeless resolves instances instead, which keeps the codebase small but hides the work inside implicit search. Neither is strictly better; they fail in different places, and the choice depends on whether your team would rather debug generated source or implicit resolution. The README does not make this comparison, and it does not claim shapeless is the only route to any of these problems.
Maintenance, releases and licence
The repository is not archived, and the last push was on 2026-09-23. The most recent release listed is v2.3.13 from 2025-03-02, preceded by v2.3.12 on 2024-05-18 and v2.3.11 on 2024-05-14. The gap between the 2024 releases and the 2025 release is roughly nine months, and the README's SBT section still refers to shapeless-2.3.3, which suggests the prose lags the artefacts. Plan upgrades around the release notes rather than the README text.
Snapshots of the main branch are built by GitHub Actions and published automatically to the Sonatype OSS Snapshot repository, so there is a continuous artifact stream separate from tagged releases. That is useful for testing a fix and risky for anything else, since a snapshot has no release note attached to it.
On licence: shapeless is Apache-2.0, and the README states it is an Open Source project under the Apache License v2, part of the Typelevel family. Apache-2.0 is a permissive licence with an explicit patent grant and a requirement to preserve notices, which is generally straightforward for commercial use. This is a description of the licence text, not legal advice; if your organisation has a policy on dependency licences, run shapeless through it like any other dependency rather than relying on a summary.
Editorial conclusion
Adopt shapeless if you are on Scala 2.11, 2.12 or 2.13 and you have a concrete arity or boilerplate problem that ordinary Scala generics cannot express. Do not adopt it for Scala 3, and do not adopt it because a blog post made heterogeneous lists look fun. Verify first that a build for your exact Scala version resolves from Maven Central, and read the feature overview and release notes before writing any code. The try script gives you a REPL in one command, which is the cheapest way to find out whether your problem is actually a shapeless problem.
Frequently asked questions
What Scala versions does shapeless support?
The README states that builds are available for Scala 2.11.x, 2.12.x and 2.13.x. Scala 3 is not listed, so a project on Scala 3 cannot use it as documented.
How do I try shapeless without adding it to my build?
The README provides a try-shapeless script that needs only an installed JDK. It downloads coursier, fetches the Ammonite REPL and the latest shapeless, and drops you straight into a REPL session.
Is shapeless documentation complete?
No. The README calls the 2.0.0 feature overview a very incomplete introduction and says the maintainers are not satisfied with the current state of the documentation. It points to The Type Astronaut's Guide to Shapeless and the release notes as additional material.
What licence is shapeless released under?
Apache-2.0. The README describes shapeless as an Open Source project under the Apache License v2 and part of the Typelevel family of projects.
Where are shapeless artefacts published?
Binary artefacts are published to the Sonatype OSS Repository Hosting service and synced to Maven Central, under the com.chuusai group. Snapshots of the main branch are published to the Sonatype OSS Snapshot repository.
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/milessabin-shapeless)