✦ 1.2KB gzipped · Zero dependencies

Your website's
night light

A warm overlay that protects your users' eyes at night. One line of code. Works with Vanilla JS, React, and Next.js.

Get started → Live demo ↗
Try it right here →
Off
Intensity 0.22
Why luxify
Built for real-world websites

Effortless setup

One function call. No plugins, no build config changes, no CSS imports.

🎯

Non-intrusive

pointer-events: none means clicks, modals, forms, and scrolling all work perfectly.

1.2KB gzipped

Zero runtime dependencies. TypeScript-first with full type exports.

🔄

Auto-scheduling

Enable at 19:00, disable at 07:00. Custom timezones supported.

💾

Persistence

Optionally save state to localStorage so users don't have to re-enable each visit.

Accessible

Respects prefers-reduced-motion. SSR-safe — no DOM access on the server.

Installation
Get started in 30 seconds
npm install @andrewbro/luxify
import { createFlux } from '@andrewbro/luxify';

const flux = createFlux({
  intensity: 0.25,   // 0–1, how warm/dark the overlay is
  color: '#ffb45c',  // any valid CSS color
  autoEnable: true,  // enable immediately
  persist: true      // remember state in localStorage
});

// Control it programmatically
flux.enable();
flux.disable();
flux.toggle();
flux.setIntensity(0.4);
flux.setColor('#ff9f43');
flux.destroy();
import { FluxProvider, FluxOverlay, useFlux } from '@andrewbro/luxify/react';

function App() {
  return (
    <FluxProvider options={{ persist: true }}>
      <FluxOverlay intensity={0.25} color="#ffb45c" />
      <Page />
    </FluxProvider>
  );
}

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 client';

import { FluxProvider, FluxOverlay } 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>
  );
}

// In layout.tsx
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <NightLightShell>{children}</NightLightShell>
      </body>
    </html>
  );
}
// Enable from 19:00 to 07:00 automatically
createFlux({
  schedule: {
    from: '19:00',
    to: '07:00',
    timeZone: 'America/New_York' // optional, defaults to browser TZ
  }
});

// Or use a fully custom callback
createFlux({
  shouldEnable: ({ hour }) => hour >= 19 || hour < 7
});

// Combine with React
<FluxOverlay
  schedule={{ from: '20:00', to: '06:00' }}
  intensity={0.3}
/>
Reference
API

createFlux(options?)

Option Type Default Description
intensity number 0.22 Overlay opacity, 0–1
color string '#ffb76b' Any valid CSS color
autoEnable boolean false Enable overlay on creation
persist boolean false Save state to localStorage
schedule { from, to, timeZone? } Auto-enable between two times (HH:MM)
shouldEnable (ctx) => boolean Custom enable logic callback
zIndex number 2147483646 CSS z-index of the overlay
transitionDuration number 240 Fade transition in ms
respectReducedMotion boolean true Disable transitions for users who prefer reduced motion
id string 'luxify-overlay' DOM element ID — reused across instances
storageKey string 'luxify' localStorage key for persisted state

Controller methods

Method Returns Description
enable()voidShow the overlay
disable()voidHide the overlay
toggle()voidToggle visibility
setIntensity(value)voidUpdate opacity (0–1)
setColor(color)voidUpdate overlay color
isEnabled()booleanCurrent visibility state
getState()FluxStateReturns { enabled, intensity, color }
update(options)voidUpdate multiple options at once
destroy()voidRemove overlay from DOM and stop scheduler