neumorphism: soft shadow widgets for Android
Try to Neumorphism in Android (Just experimental!! 🧪)
At a glance
- What is it?
- The fornewid/neumorphism project draws the extruded, single-light-source shadows that neumorphism designs need on CardView, Button, FloatingActionButton, ImageView and TextView, controlled by XML attributes for elevation, light direction and shape type. It suits a designer prototyping a neumorphic screen in Android, and the author labels it experimental sample code rather than a library.
- Who is it for?
- Adopt this project if you are prototyping a neumorphic Android screen and want the shadow treatment without writing a custom drawable, and you are comfortable with an experimental dependency pulled from JitPack. Skip it if you need a maintained widget library, since the author describes it as experimental codes and a sample project rather than a library, and the last published release is 0.3.2 from 2022-02-16 with the last push on 2026-05-28.
- 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 148 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The author calls it sample code, not a library
The fornewid/neumorphism repository is described as the experimental codes to build Neumorphism designs in Android, with the explicit note that it is not a library but a sample project. That framing matters more than usual here, because neumorphism is a style that is easy to imitate badly and hard to generalise. The project takes the approach of showing the effect in Android with a small set of widgets you can drop into a layout, and the preview art directory at the repository root carries a light and a dark preview GIF, which is the quickest way to see what the output actually looks like. The primary language is Kotlin, the licence is Apache-2.0, the project is not archived, and the last push was on 2026-05-28. The published releases are 0.3.2 on 2022-02-16, 0.3.1 on 2022-02-15 and 0.3.0 on 2020-11-16, so the code has been touched more recently than the version number suggests.
Which widgets it covers, and which it does not
The feature list is short and specific. It draws a shadow background on widgets for neumorphism, and the supported widgets are listed by superclass. For ViewGroup that is CardView, and for View it is Button, FloatingActionButton and ImageView. It also draws a text shadow on TextView, which is the piece that most attempts at this style miss, since a neumorphic surface with flat text on top immediately looks like a drop shadow pasted over a card. Anything outside that list is not handled. A plain LinearLayout, a MaterialCardView or a RecyclerView item background is not covered, which means a screen built on modern Material components will need work to make it consistent, because Material's own theming and elevation shading will fight the style unless it is switched off. The repository also asks for bug reports and feature requests through a new issue, which is how you would find out what is planned next.
Light source and shape type are the core of the look
Neumorphism is a single light source over a continuous surface, so the direction of the light and the state of the shape are the two things that define it. The `neumorph_lightSource` attribute takes one of four values, `leftTop`, `leftBottom`, `rightTop` and `rightBottom`, and the repository has an image for each. The `neumorph_shapeType` attribute takes `flat`, `pressed` or `basin`, again with an image per state, and the three are the raised element, the pressed element and the recessed one. That third state matters more than it sounds, because neumorphism without a pressed state is not a style but a decoration, and a button that does not appear to depress when touched breaks the illusion immediately. The design is also written so the light source and the shape are independent, which lets you build a raised panel with a recessed input field inside it, which is the standard arrangement in a neumorphic form.
The XML surface, and the inset that stops the clipping
The whole effect is driven from a layout file, using a custom view called `soup.neumorphism.NeumorphCardView`, which extends FrameLayout so you can wrap children inside it:
<soup.neumorphism.NeumorphCardView
style="@style/Widget.Neumorph.CardView"
app:neumorph_shadowElevation="6dp"
app:neumorph_shadowColorLight="@color/solid_light_color"
app:neumorph_shadowColorDark="@color/solid_dark_color"
app:neumorph_lightSource="leftTop|leftBottom|rightTop|rightBottom"
app:neumorph_shapeType="{flat|pressed|basin}"
app:neumorph_backgroundColor="@color/background_color"
app:neumorph_strokeColor="@color/stroke_color"
app:neumorph_strokeWidth="@dimen/stroke_width"
app:neumorph_inset="12dp"
android:padding="12dp">
<ConstraintLayout />
</soup.neumorphism.NeumorphCardView>The inset attribute is the one to understand. The comment says to use an inset to avoid clipping the shadow, with a default of 12dp, and it can be set per edge with `neumorph_insetStart`, `neumorph_insetEnd`, `neumorph_insetTop` and `neumorph_insetBottom`. The shadow is drawn outside the view bounds, so the parent has to give it room, and the inset is what reserves that room. Get it wrong and the shadow is cut off along one side, which reads as a rendering bug rather than a configuration mistake. The padding attribute serves a different purpose, giving space between the surface and the content inside it, and it also defaults to 12dp.
Corner radii, per corner, through a style
The shape of the corners is controlled through a style attribute rather than a layout attribute, `neumorph_shapeAppearance`, which points at a style resource. Inside that style you set `neumorph_cornerFamily` to `rounded` or `oval`, and `neumorph_cornerSize` for a uniform radius, or the four per-corner values `neumorph_cornerSizeTopLeft`, `neumorph_cornerSizeTopRight`, `neumorph_cornerSizeBottomLeft` and `neumorph_cornerSizeBottomRight` if you want them to differ. The example uses a uniform 32dp for the simple case and 16dp on each corner for the mixed case. The reason this is a style and not an attribute is that the corner family and radii describe the appearance of the surface, and in Android an appearance is a style, so the mechanism follows the platform rather than inventing a new one. A pre-defined style is also shipped, `Widget.Neumorph.CardView`, which the example applies through the ordinary `style` attribute.
Installing from JitPack
The dependency comes from JitPack, and it takes two Gradle edits. First, in the root `build.gradle` file and not the module one, you add the JitPack repository:
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}Then in your module `build.gradle` you add the library itself:
dependencies {
implementation 'com.github.fornewid:neumorphism:{latest_version}'
}The `com.github.fornewid` coordinate is the JitPack convention, the group is the GitHub user and the artifact is the repository name. The `{latest_version}` placeholder is literally what the README shows, so you have to substitute a real tag yourself. The JitPack route is a real trade-off worth naming. It is the standard way to consume a library that is not published to Maven Central, and it works, but it means your build depends on a third-party build service that compiles the project on request rather than on a published artifact, and that is a different supply chain story from a Central release.
The sample projects in the tree
The repository root shows a multi-module Gradle project rather than a single library module. There is the `neumorphism/` module that is the library itself, and then three sample modules: `sample-app/`, `sample-ui/` and `sample-benchmark/`. The README links a sample under a `sample` path that shows how to use the library, and the presence of a separate `sample-ui` and `sample-benchmark` module suggests the author was measuring the cost of the shadows as well as demonstrating them, which is a reasonable thing to check given that a neumorphic surface draws multiple shadow layers. There is also an `art/` directory holding the preview images and the per-value illustrations for the light source and shape type, a `gradle.properties`, a `settings.gradle` and the usual `gradlew` and `gradlew.bat` wrappers. The repository carries an `art/preview.png` banner as well as the two theme GIFs.
Editorial conclusion
Adopt this project if you are prototyping a neumorphic Android screen and want the shadow treatment without writing a custom drawable, and you are comfortable with an experimental dependency pulled from JitPack. Skip it if you need a maintained widget library, since the author describes it as experimental codes and a sample project rather than a library, and the last published release is 0.3.2 from 2022-02-16 with the last push on 2026-05-28. Before you build on it, read the XML attributes carefully, because the `neumorph_inset` value exists to stop the shadow being clipped, and if you set it to zero your shadows will be cut off at the parent boundary.
Frequently asked questions
How do I add the neumorphism library to an Android project?
Add the JitPack repository in your root build.gradle with `maven { url "https://jitpack.io" }` inside allprojects repositories, then in your module build.gradle add `implementation 'com.github.fornewid:neumorphism:{latest_version}'`, substituting a real tag for the placeholder.
Which Android widgets does the neumorphism library support?
For shadow backgrounds it supports the ViewGroup CardView and the View Button, FloatingActionButton and ImageView, and it also draws a text shadow on TextView. The custom view is soup.neumorphism.NeumorphCardView, which extends FrameLayout so you can wrap children inside it.
What are the shape types and light sources in neumorphism?
The neumorph_shapeType attribute takes flat, pressed or basin, and the neumorph_lightSource attribute takes leftTop, leftBottom, rightTop or rightBottom. The repository ships an illustration for each value.
Why is my neumorphism shadow cut off?
The shadow is drawn outside the view bounds, so the parent has to leave room for it. The neumorph_inset attribute does that and defaults to 12dp, and it can be set per edge with neumorph_insetStart, neumorph_insetEnd, neumorph_insetTop and neumorph_insetBottom.
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/fornewid-neumorphism)Was this useful?