react-skylight: a small React modal with four lifecycle callbacks
A react component for modals and dialogs
At a glance
- What is it?
- react-skylight is a single-component React modal library whose entire feature list is nine items, most of them lifecycle callbacks around opening and closing. It is MIT licensed and reads like code from the React 15 era, which is both its charm and its limitation.
- Who is it for?
- Adopt react-skylight if you want a modal with no styling framework attached, you need callbacks either side of the open and close transitions, and you are on a React version the peer dependency range covers. Do not adopt it for a new application on a current React release, because the peer range stops at 16.3.0 and the last tagged version is 0.5.1 from 2018.
- 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?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly JavaScript, 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
Nine features, most of them callbacks
React SkyLight is a simple react component for modals and dialogs, described as lightweight and customizable in design.
The feature list is short enough to print, and it tells you what kind of component this is. There is a very simple modal or dialog, animation support, and a stateless API. Then six callbacks: callback before open, callback after open, callback before close, callback after close, and callback on overlay click. And then the one that matters most for anyone with a design system, all styles can be overridden.
That is the whole component. There is no portal layer, no focus trap, no scroll locking, no router integration and no animation library dependency, at least as far as the documentation goes. What there is instead is a set of hooks around the transitions, which is a different bet.
The four open and close callbacks are the distinguishing feature. Most modal libraries give you a single onRequestClose or onClose. This one separates the moment before opening from the moment after, and the moment before closing from the moment after, so you can do work in the gap: disable a button before the dialog is visible, or start a transition after the close animation finishes rather than during it.
The overlay click callback is separate again, so clicking the backdrop can be treated differently from pressing the escape key or calling close programmatically.
Installation is one npm command, and the component is stateless
Installing is the usual pair of commands:
$ npm install react-skylight --save
# Installation via Yarn
$ yarn add react-skylightThe stateless API is the other thing to understand before you use it. A stateless modal means the component does not hold the open or closed state itself. You keep it in your own component's state and pass it down, which means the dialog is controlled by whatever owns the state, and you can drive it from anywhere in your tree without a ref or a context.
That design has a cost and a benefit, and they are the usual ones. The cost is that every consumer has to wire the state, and the open and close callbacks become the place where you do it. The benefit is that the component never gets out of sync with your application, and a dialog that is open because your state says so is much easier to reason about than one that is open because the library decided to open it.
The package itself is tiny in dependency terms. The runtime dependencies section lists one entry, prop-types, and the peer dependency is React. The main entry point is lib/index.js, and the build is a Babel compile from src to lib with a watch script alongside and jest for the tests.
Style overrides are the point for anyone with a design system
All styles can be overridden is listed as a feature, and for a component whose selling point is that it brings no styling framework with it, that is the load-bearing one.
A modal has a lot of surface area that a design system wants to control: the overlay colour and opacity, the dialog background, the border radius, the shadow, the title typography, the button row, the z-index, the width and the transition. A component that hardcodes any of those is unusable in a system with its own tokens, and a component that requires a styling library is a dependency you may not want.
The alternative, which is the one this library takes, is to make the styles plain props and let the consumer pass them. The trade is that you get no consistent defaults and no system out of the box; you get a component that will not fight you.
The release history also shows a design decision about the dialog's own styling. Version 0.4.0 fixed a numeric string value for a CSS property, and the most recent entry, v0.5.1, changed the dialog style height to minHeight, added React 16 support, and removed unused dependencies. That is a component whose style surface is prop driven, and whose height behaviour was adjusted to a value that adapts to content rather than a fixed number.
The release history dates from the React 15 and 16 era
The release history section in the README is a plain list of dated versions with a one-line summary, and it is worth reading for what it says about the project's shape.
Version 0.5.1 on 2018-04-03 changed the dialog style height to minHeight, added React 16 support and removed unused dependencies. Version 0.5.0 on 2017-09-20 added animation, added ESC to close, allowed the title to be a component, and fixed some issues. Version 0.4.2 in May 2017 solved propTypes warnings. Version 0.4.1 in August 2016 polyfilled Object.assign so the component would work in IE. Version 0.4.0 in April 2016 fixed a numeric string value for a CSS property and added support for the stateless API. Version 0.3.0 in January 2016 was a rewrite to ES2015 with an overlay callback and a new site. Before that, v0.2.0 and v0.1.4 in 2015 were improvements and a namespace adjustment.
The features accumulate in a specific order. Animation and ESC to close arrive together in the same minor version, which is when the component stopped being a bare overlay. Stateless support arrives as a change rather than a redesign, which is the migration that made the current API possible.
The peer dependency range in the manifest says the same thing from the other side: react ^0.14.0 or ^15.0.1 or ^16.3.0. A library that supported React 0.14 and needed an Object.assign polyfill for Internet Explorer is a library whose last functional change was in 2018.
The last push to the master branch was on 2026-04-09, so something is still happening on the branch, and the repository publishes no GitHub releases, so the versions above are recorded only in the README.
The documentation is a demo site, and that is the whole reference
There is no written documentation site for this component, and the README says so by linking the same page twice: React skylight DEMOS and DOCS, pointing at marcio.github.io/react-skylight, in the introduction and again in the How to use section, followed by a single word, Enjoy!
So the demos are the documentation. That has a specific consequence for an adopter: you cannot skim a prop table, you have to open the demo page and look at what each example does. For a component with nine features and one prop-driven style surface, that is workable, and the examples are arguably a better way to understand the callbacks than a table of prop types would be, because you can see the ordering of the events happen.
It is also a risk. A component whose only reference is a hosted demo page has no versioned documentation, so there is nothing to link to in a wiki entry, and the demo site can drift from the published package without anyone noticing.
The repository structure is small and matches the age of the project. There is a src/ directory for the source, a lib/ directory for the Babel output, a test/ directory with jest.config.js, a babel.config.js, an .eslintrc, an .npmignore, a yarn.lock and a package.json. The eslint setup is the airbnb config with eslint-plugin-react at version 7, which is the linting convention of that period.
The author is Marcio Gasparotto, with one listed contributor, Chris Trevino, who is credited in the release history for the stateless support work in v0.4.0.
How this compares to a styled modal library
The realistic alternative is one of the modal libraries that ships with a styling system attached, and the difference in approach is mostly about what you are buying.
A styled modal library gives you a complete, opinionated dialog: focus trapping, scroll locking, escape handling, aria attributes, a portal to the document body, and a set of themeable tokens. You get accessibility behaviour that is hard to get right yourself, and you get a look that matches the library's design language unless you override enough of it to be maintaining your own theme anyway.
react-skylight gives you the opposite. It is a rendering of a dialog with the transitions exposed, the styles yours to set, and the state yours to hold. What it does not give you is the accessibility and focus management work, and the documentation does not mention focus trapping, aria attributes, or portal rendering at all, so you should assume you are handling those yourself if you need them.
The case for the small option is that most modal libraries solve problems you may not have. If your dialog is a settings form inside an application that already has a routing and a focus strategy, adding a second opinion about focus is overhead. And for a component whose entire job is to be in your way for three seconds, a lightweight implementation with hooks around the open and close is often exactly the right size.
The case against is that the accessibility gap is not hypothetical. A modal that does not trap focus lets a keyboard user tab into the page behind it, and no amount of clean callbacks fixes that. If you are shipping this to users rather than to yourself, budget for the accessibility work, and check whether your React version is even in the supported range.
Editorial conclusion
Adopt react-skylight if you want a modal with no styling framework attached, you need callbacks either side of the open and close transitions, and you are on a React version the peer dependency range covers. Do not adopt it for a new application on a current React release, because the peer range stops at 16.3.0 and the last tagged version is 0.5.1 from 2018. Before you install, check the peer dependency range in package.json against your React version, and note that the documentation is a demo site rather than a written guide, so the demos are where you will find the actual API.
Frequently asked questions
How do I install react-skylight?
Run `npm install react-skylight --save`, or `yarn add react-skylight` if you use Yarn. The component is stateless, so you also need to hold the open and closed state in your own component and pass it down.
What callbacks does react-skylight provide?
There are six: callback before open, callback after open, callback before close, callback after close, and callback on overlay click. Separating the before and after variants lets you do work in the gap around the open and close transitions.
Which React versions does react-skylight support?
The peer dependency in package.json allows react ^0.14.0, ^15.0.1 or ^16.3.0. The most recent tagged version is 0.5.1 from 2018-04-03, which added React 16 support and removed unused dependencies.
Where is the documentation for react-skylight?
There is no written documentation site. The README links a demos and docs page at marcio.github.io/react-skylight twice, in the introduction and in the How to use section, so the hosted examples are the reference for the API.
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/marcio-react-skylight)Was this useful?