βββ βββ ββββββ βββββββββββββββββ βββ
βββ βββ ββββββββββββββββββββββββββ ββββ
βββ βββ βββ ββββββ βββββββββ βββββββ
βββ βββ βββ ββββββ βββββββββ βββββ
βββββββββββββββββββββ βββββββββ βββ
ββββββββ βββββββ βββ βββββββββ βββ
Stop hurting your eyes while browsing at night.
luxify transforms any website into a comfortable evening reading experience. Instead of fighting blue light with system settings, bring it right into your web appβinstantly. No configuration nightmares. No broken layouts. Just warm, gentle browsing.
It's 10 PM. You're checking email, reading docs, or browsing your dashboard. Your eyes start burning. You reach for f.lux or Night Shift, but they're global, clunky, and don't work on everything. What if your app could just... care about your eyes?
luxify adds a warm overlay directly on top of your website. It's:
β¨ Effortless β One line of code. No setup. No configuration.
π― Safe β Doesn't break clicks, scrolling, modals, or forms.
β‘ Lightweight β 1.2KB gzipped. TypeScript. Zero dependencies.
π Smart β Optional auto-scheduling (enable at sunset, disable at sunrise).
βΎοΈ Works Everywhere β Vanilla JS, React, Next.js, any framework.
Ready to care about your users' eyes?
See it in action at toopost.us β toggle night mode directly in the app.
Reading-heavy websites where users spend hours:
- π Documentation sites (Think Docs, API references)
- π Blogs & content platforms (Medium, Substack, news sites)
- π Dashboards & analytics (Long evening work sessions)
- π¬ Community forums & chat (Discord, Slack web version)
- π Learning platforms (Courses, tutorials, coding challenges)
Already have a dark mode? luxify is the perfect companion. Layer it on top:
import { useState } from 'react';
import { FluxProvider, FluxOverlay } from '@andrewbro/luxify/react';
export function App() {
const [isDark, setIsDark] = useState(false);
return (
<div data-theme={isDark ? 'dark' : 'light'}>
<FluxProvider>
{/* Night mode layer on top of your existing theme */}
<FluxOverlay
intensity={0.22}
color={isDark ? '#1a1a2e' : '#ffb76b'}
/>
<YourApp />
</FluxProvider>
</div>
);
}Or auto-enable night mode in dark themes, disable in light:
const [isDark, setIsDark] = useState(false);
<FluxOverlay
intensity={isDark ? 0.15 : 0} // Subtle in dark mode, off in light
autoEnable={isDark}
/>npm install @andrewbro/luxifyIf you want the React API, install React 18+ in your app as usual.
import { createFlux } from '@andrewbro/luxify';
const flux = createFlux({
intensity: 0.25,
color: '#ffb45c',
autoEnable: true,
persist: true
});
flux.enable();
flux.disable();
flux.toggle();
flux.setIntensity(0.4);
flux.setColor('#ff9f43');
flux.destroy();React exports live under @andrewbro/luxify/react to keep the core entry lightweight for non-React sites.
import { FluxOverlay, FluxProvider } from '@andrewbro/luxify/react';
function App() {
return (
<FluxProvider options={{ persist: true }}>
<FluxOverlay intensity={0.25} color="#ffb45c" />
<Page />
</FluxProvider>
);
}import { useFlux } from '@andrewbro/luxify/react';
function Page() {
const { toggle, setIntensity } = useFlux();
return (
<div>
<button onClick={toggle}>Toggle night mode</button>
<button onClick={() => setIntensity(0.35)}>Make it warmer</button>
</div>
);
}Use the React API in a client component.
'use client';
import { FluxOverlay, FluxProvider } from '@andrewbro/luxify/react';
export function NightLightShell({ children }: { children: React.ReactNode }) {
return (
<FluxProvider options={{ persist: true }}>
<FluxOverlay
intensity={0.22}
color="#ffb76b"
schedule={{ from: '19:00', to: '07:00', timeZone: 'Europe/Warsaw' }}
/>
{children}
</FluxProvider>
);
}Creates a controller for a single overlay instance.
type FluxOptions = {
intensity?: number;
color?: string;
zIndex?: number;
transitionDuration?: number;
autoEnable?: boolean;
respectReducedMotion?: boolean;
id?: string;
storageKey?: string;
persist?: boolean;
schedule?: {
from: string;
to: string;
timeZone?: string;
};
shouldEnable?: (context: {
date: Date;
hour: number;
minute: number;
timeZone?: string;
}) => boolean;
};Defaults:
intensity: 0.22color: '#ffb76b'zIndex: 2147483646transitionDuration: 240autoEnable: falserespectReducedMotion: trueid: 'luxify-overlay'storageKey: 'luxify'persist: false
enable()disable()toggle()destroy()setIntensity(value)setColor(color)isEnabled()getState()update(options)
Enable the overlay during the evening and disable it in the morning:
createFlux({
schedule: {
from: '19:00',
to: '07:00'
}
});Use a callback for fully custom logic:
createFlux({
shouldEnable: ({ hour }) => hour >= 19 || hour < 7
});If you need a specific local clock instead of the browser default, pass schedule.timeZone.
- Use
intensitybetween0and1 - Use any valid CSS color for
color - Use
zIndexif your app needs a custom stacking level - Use
respectReducedMotionto disable transitions for users who prefer reduced motion - Use
persist: trueto storeenabled,intensity, andcolorinlocalStorage
- The overlay uses
position: fixed,inset: 0,pointer-events: none, and a very highz-index - The library reuses the same DOM node per
id, so repeated mounts do not create duplicate overlays - DOM access happens only in the browser, making the package safe to import in SSR environments
- This is a page-level visual layer only, not a true monitor or operating-system night light
npm install
npm run build
npm run test