react-native-shadow-2 gives one shadow API across Android, iOS and web
🥷 Cross-platform shadow for React Native. Supports Android, iOS, Web, and Expo
At a glance
- What is it?
- react-native-shadow-2 is a TypeScript React Native component that draws a gradient shadow with react-native-svg so the result looks the same on Android, iOS and web, with Expo support and RTL handling. Its own README now recommends the platform boxShadow style that React Native 0.76 added, so the library is a compatibility layer for older versions.
- Who is it for?
- react-native-shadow-2 suits a React Native app that is not on React Native 0.76 or later and needs a consistent shadow on Android, iOS and web, since the SVG based implementation gives the same result everywhere and the properties cover offsets, per-side and per-corner control. It is the wrong choice for a new project on React Native 0.76 or later, because the platform boxShadow and filter style props should be preferred and the library says so itself.
- Can I use it commercially?
- Yes. MIT 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 69 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it was written to solve
react-native-shadow-2 is a cross-platform shadow for React Native, supporting Android, iOS, Web and Expo, and it exists because the platform did not provide one that behaved the same everywhere.
The README states the problem directly: it solves the old React Native issue of not having the same shadow appearance and usage for Android, iOS, and Web. Before React Native grew a native shadow, Android drew an elevation shadow that followed the Material elevation model and iOS drew a completely different one, and the web had neither. A designer with a single shadow spec in a design tool had no way to reproduce it on all three.
The library is an improved version of react-native-shadow, which the README describes as dead for years, with more functionalities, TypeScript support, and written from scratch. It also states that it is not required to define its size: the shadow is smartly applied on the first render and then precisely reapplied on the following ones.
That last point is the core of the implementation. The component measures its child and derives the shadow geometry from that measurement, so you do not have to tell it how big the shadow should be.
The repository topics include shadow, gradient, cross-platform, expo, mobile and web, and the author is Bruno Fantauzzi.
How the shadow is drawn
The implementation is SVG based, and that is what produces the cross-platform consistency rather than a set of per-platform hacks.
The installation instructions make the dependency explicit: first install react-native-svg, and the latest react-native-svg version is recommended, including if using Expo. The package.json lists react-native-svg at 12.1.0 or later in both devDependencies and peerDependencies, and the only runtime dependency is colord at 2.9.2, which is a colour manipulation library.
The gradient in the shadow comes from those two pieces together. The SVG layer can draw a gradient fill, and colord handles the colour maths, including the alpha values that make the far end of the shadow transparent.
The properties table is where the design of the component becomes clear, and every property is optional. The defaults are startColor '#00000020', a black at 12.5 percent alpha, and endColor transparent, which the README explains with a link to an issue comment. The distance property defaults to 10 and controls how far the shadow goes, and the offset property moves the shadow, with negative x moving it left or start and negative y moving it up, accepting percentage values of the form 'x%'.
Two defaults are conditional rather than fixed, which is worth noting. Defining an offset defaults paintInside to true, because that is the usual desired behaviour, and paintInside applies the shadow below or inside the content, using startColor as a flat fill with no gradient, which is useful when using offset or when the child has some transparency.
Controlling which sides and corners get a shadow
The sides and corners properties are the ones that let the component imitate a specific design rather than a generic glow.
The sides property is a Record of start, end, top and bottom booleans, and it says plainly that it does not include corners. Undefined sides fall back to true, so a partial specification only turns off the sides you name. There is a link to an issue comment explaining the behaviour.
The corners property works the same way with topStart, topEnd, bottomStart and bottomEnd, and again undefined corners fall back to true.
The start and end keys rather than left and right are what make the component RTL aware, and the README says it supports RTL explicitly. The Notes section makes the same point about radii: you can use either the borderTopLeftRadius or the borderTopStartRadius and their variations to define the corner radii, although the author recommends the latter as it is the RTL standard.
The stretch property, defaulting to false, makes the children occupy all available horizontal space, which matters when the child is not a fixed width element and the shadow needs to follow the full row.
The sizing rules, and the safeRender escape hatch
The Notes section is the densest part of the README and it describes a set of rules that will otherwise surprise you.
If the Shadow has a single child, it gets the width, height and all of the borderRadius properties from the child's style property, if defined. You may also define those properties in the Shadow's own style, and the ones defined there have priority over the child's. And if the width and height are defined in either place, there will be only a single render, because the first automatic sizing will not happen, only the precise render.
The rule that matters most in practice is the one about radii. Having a radius greater than its side will mess the shadow if the sizes are not defined, and the README points to an issue on the subject. The safeRender property is the answer: it does not use the relative sizing and positioning on the first render but on the following renders with the exact onLayout sizes, which avoids the visual artifact. Its cost is stated plainly: if true, the Shadow will not appear on the first render.
That is a real trade-off, and it is a good sign that the library documents it. A component that renders a wrong-looking shadow for one frame and then corrects itself is better than one that renders nothing, but neither is ideal, and safeRender is the switch between them.
The radius limit is another concrete constraint: radii greater than 2000 may crash Android, and the README notes that Tailwind's rounded-full is 9999. So a component using a fully rounded style has to be checked on Android specifically.
The disabled property, defaulting to false, turns the shadow off while still applying containerStyle and style, which is the convenient way to reuse the same component in a list where shadows are not wanted on some rows.
Installing it and the first render
The installation is two steps, and the order matters because the SVG dependency has to be in place first.
npm i react-native-shadow-2
# or
yarn add react-native-shadow-2The usage is a single import and a wrapper around your children:
import { Shadow } from 'react-native-shadow-2';
<Shadow>
<Text style={{ margin: 20, fontSize: 20 }}>🙂</Text>
</Shadow>And with the gradient configured, which is the case that shows what the component is for:
<Shadow distance={15} startColor={'#eb9066d8'} endColor={'#ff00ff10'} offset={[3, 4]}>
<View style={{ borderTopStartRadius: 24, borderBottomEndRadius: 0, borderRadius: 10, backgroundColor: '#c454f0dd' }}>The start and end colours are hex strings with alpha, and the offset is a two element array. The View inside uses mixed corner radii, with borderTopStartRadius and borderBottomEndRadius set, which is exactly the kind of asymmetric shape the per-corner controls exist for.
The repository also has a sandbox directory and a script for it. The package.json defines the sandbox script as npm run --prefix ./sandbox web, and the README links a demo in the Expo Snack Sandbox, which is the quickest way to see the component without installing anything in a project.
The package version in package.json is 7.1.2, the main entry is lib/index.js with types at lib/index.d.ts, and the build is a plain tsc compile with rimraf cleaning the lib directory first.
The recommendation to stop using it on React Native 0.76
The first thing in the README is an IMPORTANT callout, and it changes how you should read everything below it.
The new React Native 0.76, released on Oct 23, 2024, finally supports a cross-platform shadow, through the boxShadow and filter style props. This new feature should be preferred over this library.
So the library is now, in the author's own words, a compatibility layer for older React Native versions. That is not a criticism, it is a status. The component is well built, TypeScript typed, and supports Android, iOS, web and Expo with a consistent result, and none of that is needed if the platform now does the same thing natively.
The release record bears this out. The tagged releases are v7.1.1 from 2024-10-26, v7.0.7 from 2023-04-14 and v7.0.0 from 2022-08-10, and the last push to the repository was on 2026-08-18. The v7.1.1 release is dated one day after the React Native 0.76 announcement, which reads like a response to it.
The README also carries a short, human note about the project's history, thanking supporters over the past 4 years. The reading it supports is that the library found its audience and matured before the platform offered an equivalent, and the announcement of that platform feature is what closed the gap.
Licensing, and what the package metadata says
There is a small inconsistency in the licence information that is worth resolving before you ship it.
GitHub shows MIT in the licence field, and the README does not state a separate licence section. The package.json, however, has a license field that reads ISC, and the LICENSE file in the repository is the authoritative text if the two disagree. For a component you intend to include in a proprietary app, the practical effect is minimal, since both MIT and ISC are permissive, but a mismatch between the npm metadata and the repository is the kind of thing that trips a licence audit in a large company.
The author is Bruno Fantauzzi, and the npm package is react-native-shadow-2, published with the homepage pointing at the repository README.
The other maintenance signal is the dependency floor. react-native-svg is required at 12.1.0 or later as a peer dependency, which means anyone installing this library has to be on a reasonably current react-native-svg, and the library's own devDependencies use wildcard versions for react and react-native, so the build is not pinned to a single React Native generation.
Editorial conclusion
react-native-shadow-2 suits a React Native app that is not on React Native 0.76 or later and needs a consistent shadow on Android, iOS and web, since the SVG based implementation gives the same result everywhere and the properties cover offsets, per-side and per-corner control. It is the wrong choice for a new project on React Native 0.76 or later, because the platform boxShadow and filter style props should be preferred and the library says so itself. Before adopting it, install react-native-svg at version 12.1.0 or later, check whether the gradient shadow is what your design calls for rather than a blur, and note that the published package metadata lists ISC while the repository is described as MIT.
Frequently asked questions
How do I install react-native-shadow-2?
Install react-native-svg first, since the shadow is drawn with it and the latest version is recommended, including with Expo. Then add the library with npm i react-native-shadow-2 or yarn add react-native-shadow-2. The package requires react-native-svg 12.1.0 or later as a peer dependency.
Should I still use react-native-shadow-2 on React Native 0.76 or later?
The README says no. It notes that React Native 0.76, released on Oct 23, 2024, finally supports a cross-platform shadow through the boxShadow and filter style props, and that this new feature should be preferred over the library.
How do I control which sides and corners of react-native-shadow-2 get a shadow?
The sides property takes a Record of start, end, top and bottom booleans and does not include corners, while the corners property takes topStart, topEnd, bottomStart and bottomEnd. Undefined sides or corners fall back to true, so naming only some of them turns off just those.
What does the safeRender property do in react-native-shadow-2?
It skips the relative sizing and positioning on the first render and uses the exact onLayout sizes on the following renders, which avoids visual artifacts when a radius is greater than the side size, such as a circle. The cost is that the shadow will not appear on the first render.
What licence is react-native-shadow-2 under?
GitHub shows MIT in the licence field, while the package.json license field reads ISC. Both are permissive, but the LICENSE file in the repository is the authoritative text if you need one specific answer for a licence audit.
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/ftzi-react-native-shadow-2)Was this useful?