# Neumorphism Button in React Native: A Build Guide

> Published 2026-10-26T00:42:08.740Z on https://youblog.app/p/neumorphism-button-in-react-native-a-build-guide/
> Source video: https://www.youtube.com/watch?v=fmEnVAYQ8Z8

If your neumorphism button in React Native looks flat, crooked, or just like a blurry rectangle, the problem is usually the shadow offset and the button color, not the library. The fix is to match the fill to the page background and let a single shadow do the carving, then center the control and give it a fixed width so it stops drifting.

## How do you build a neumorphism button in React Native?

A neumorphism button in React Native is a monochrome button whose fill matches the page background and whose shadow makes it look pressed into the surface. You build one by wrapping a styled pressable inside the Shadow component from [react-native-neomorph-shadows](https://github.com/SrBrahma/react-native-neomorph-shadows), a community package that renders adjustable inner and outer shadows.

The technique became visible in late 2019 and was still being taught in React Native tutorials through 2020, when the video source for this guide was published on 5 July 2020 by the channel Gustavo Dev Doido. The design stays legible only when three things agree: background color, button fill, and one soft shadow.

React Native's built-in shadow props give a view a single shadow on iOS and a single elevation value on Android. A recessed control needs the light to fall on one side and the surface to read darker around the edges, so a library that lets you set offset, opacity, radius and direction separately does most of the visual work.

Here is the minimum part list for the build:

- `react-native-neomorph-shadows` for the Shadow wrapper
- A component folder holding a shadow-button file and a matching styles file
- `styled-components` for the exported style classes
- An `ActivityIndicator` for the button's loading state

The rest is layout. Center the wrapper, set an explicit width, and keep the text color tied to the same palette as the fill.

## What shadow settings make the pressed effect work?

The pressed effect comes from a small shadow offset, low opacity, and a radius large enough to blur the edges softly. In the original 2020 walkthrough the settings were an 8-pixel offset, 0.3 opacity, and a radius near 28 pixels, with the presenter noting that he spent about two hours adjusting the values before the button sat naturally on his screen background.

Treat those numbers as a starting point rather than a rule. Shadow intensity depends on your background color, your device pixel density, and how large the button is, so the same offset that looks carved on a light gray page will look flat on white and heavy on a dark theme.

The author of the library documents the Shadow component's props as `inner`, `useArt`, `width`, `height`, `borderRadius`, `shadowRadius`, `shadowOffset`, `shadowOpacity`, `shadowColor` and `backgroundColor`; check the [current documentation](https://github.com/SrBrahma/react-native-neomorph-shadows) before copying older snippets, since prop names and defaults can change between releases.

A practical tuning order:

1. Set the button fill to the same color as the page background.
2. Raise opacity until the edge is visible but not gray.
3. Increase the shadow radius until the transition looks soft.
4. Adjust the offset last, since it controls which side appears lit.

If the button still looks tilted, the cause is usually layout, not shadow. An explicit width plus `align-self: center` on the wrapper fixes most of it.

## How do you structure the component and its styles?

Split the button into one file for the styled classes and one for the component. The styled file exports a container class with a fixed height, a fixed width, a 4-pixel radius, and centered content, plus a text class with bold weight and a 16-pixel font size. The component file imports the Shadow wrapper, the loading indicator, and the exported classes.

The component takes `children` as the label string, `loading` as a boolean defaulted to false, and the remaining props spread onto the inner touchable. When `loading` is true the button renders an `ActivityIndicator` instead of the text, which keeps the control's box size stable while a request runs.

Color handling is where most implementations drift. The 2020 version passed a single color prop into both the Shadow background and the text color. That works for monochrome neumorphism, where the label sits a shade or two away from the fill. If you introduce a bright primary color, test contrast: light text on a light fill fails readability even when the shadow looks correct.

A common complaint in the original build was that the button arrived slightly crooked and looked unattractive on first render. The fix was not more shadow tuning. Adding an explicit 250-pixel width and centering the text solved it, which is a reminder that neumorphism hides layout mistakes less forgivingly than a bordered button does.

## Does neumorphism work on Android and iOS the same way?

No, and the difference is structural rather than cosmetic. React Native supports only one shadow per view on iOS and exposes a single elevation value on Android, while a true neumorphic surface often implies two opposing shadows, one light and one dark. That limitation is why a dedicated multi-shadow package is part of the build.

Libraries such as [react-native-shadow-2](https://github.com/Intellicode/react-native-shadow-2) provide multi-shadow support as an alternative path, and some teams wrap two nested views so the outer view carries the dark shadow and the inner one the light. Inner shadows for pressed states typically need an SVG-based approach or pre-rendered artwork.

Cross-platform consistency also depends on how the shadow is drawn. A real styled shadow and a simulated SVG shadow can differ in softness at the same radius, so verify on a physical Android device as well as an iOS simulator before shipping a palette that depends on subtle relief.

The accessibility cost of neumorphism deserves a line of its own. Low-contrast, shadow-only affordances are harder to perceive for users with low vision, and a pressed look gives no hover or focus cue on its own. Pair the shadow with a visible label, a minimum touch target, and a press state that changes something other than shadow depth.

## Where does an auth flow with Redux Saga and TypeScript fit?

The same channel that published the neumorphism lesson later taught an authentication flow built around Redux Saga, a middleware library for handling side effects in Redux, and TypeScript. Button styling and state management are separate concerns, but a login button is where they meet: the component needs a `loading` boolean that reflects the saga's request lifecycle.

A workable pattern is to keep the button dumb. It receives `loading` and an `onPress` handler, renders an `ActivityIndicator` while a request is pending, and never imports the store. The screen connected to Redux decides when loading is true, which keeps the shadow component reusable outside the login form.

Naming matters here. The channel's content and community material circulate under the names Gustavo Dev Doido and Dev doido, and the styling lesson is often filed under a course or stack label rather than a library name. If you are searching for the original build, search the video title rather than the component name.

Related React Native material from the same ecosystem includes [Crazystack](https://crazystack.com.br), a Brazilian course platform, and its Crazystack TypeScript track covering typed React Native application structure. Those resources cover project organization rather than shadow geometry, so treat them as complements to this guide, not sources for shadow values.

## Which settings should you copy and which should you tune?

Copy the component shape and tune the visual constants. The file layout, the `loading` prop, the spread of remaining props onto the inner touchable, and the centered wrapper are structural decisions that survive a redesign. The shadow offset, opacity, and radius are device- and palette-dependent values that need your own screen.

Use this split as a working checklist:

| Setting | Copy or tune | Why |
| --- | --- | --- |
| File structure | Copy | Two files keep styles readable and reusable |
| `loading` prop with default false | Copy | Keeps the button size stable during requests |
| Button width | Tune | Depends on form layout and label length |
| Shadow offset and opacity | Tune | Depends on background color and pixel density |
| Text color | Tune | Must pass contrast against the fill |
| Radius | Tune | 4 pixels suited the demo, not every brand |

One more decision: whether the shadow belongs inside the touchable or around it. Wrapping the touchable in the Shadow component, as the 2020 build did, keeps press handling on the inner view and avoids the shadow intercepting touches. Verify that behavior on both platforms, because shadow libraries draw in different layers.

## Frequently asked questions

- **What is a neumorphism button in React Native?** It is a monochrome button whose fill matches the surrounding background and whose soft shadow makes it appear pressed into the surface. The effect relies on low-contrast shading rather than borders or bright fills.

- **Which library draws the shadow?** The 2020 build used react-native-neomorph-shadows, a community package that exposes offset, opacity, radius, and inner-shadow props. Check its current README for the supported prop names before copying old snippets.

- **Why does my button look crooked?** Missing layout constraints usually cause it. Set an explicit width and center the wrapper; the shadow then follows the box instead of the surrounding content.

- **Can I use multiple shadows without a library?** Not directly in React Native, which supports one shadow per view on iOS and a single elevation on Android. Multi-shadow packages or nested views are the usual workarounds.

- **What shadow values should I start with?** An 8-pixel offset, 0.3 opacity, and a radius near 28 pixels matched one light demo background in 2020. Tune from there against your own palette and a physical device.

- **Does neumorphism hurt accessibility?** It can. Shadow-only affordances are hard to perceive and provide no focus cue, so keep a visible label, adequate contrast, and a touch target large enough to hit.

- **Can the button show a loading state?** Yes. Accept a `loading` boolean and render an ActivityIndicator in place of the label while a request runs, which is the pattern used in the original component.

- **Where does Redux Saga come in?** Saga handles side effects such as login requests, and the connected screen passes the resulting loading flag into the button. The button itself stays unaware of the store.

- **Is the technique still current?** The visual style persists, but library APIs move. Treat the 2020 code as a starting reference and confirm prop names against the package's current documentation before shipping.

## Turn the tutorial you already recorded into a written guide

A neumorphism lesson lives or dies on details that are easy to say out loud and tedious to describe: the exact offset, the opacity that finally looked right, the two hours spent nudging values. Those details already exist in your recording, along with the reasoning behind each one.

Skala blog turns that recording into a draft article. Paste a YouTube URL, let the video be transcribed, and generate a structured piece that keeps the tuning steps, the code structure, and the caveats in written form, ready for you to review and publish.

If you have taught a React Native technique on camera, the explanation is already done. Moving it into text gives readers something they can search, skim and copy from.

[Source video](https://www.youtube.com/watch?v=fmEnVAYQ8Z8)
