
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
lightswitch-js
Advanced tools
A minimal SDK for subscription management, entitlements, and paywalls.
npm install lightswitch-js
yarn add lightswitch-js
pnpm add lightswitch-js
lightswitch-sdk-js/
├── index.js # Main entry point
├── README.md # This file
│
├── components/ # React Components
│ ├── LightswitchProvider.jsx # Main provider component
│ └── ProtectedRoute.jsx # Route protection component
│
├── hooks/ # React Hooks
│ ├── useLightswitch.js # Main SDK hook
│ ├── useAuth.js # Authentication hook
│ └── useEntitlement.js # Entitlement checking hook
│
├── core/ # Core Vanilla JS
│ ├── index.js # Core SDK entry
│ ├── api.js # API communication
│ ├── auth.js # Authentication logic
│ ├── config.js # Configuration
│ ├── entitlement.js # Entitlement checking
│ ├── paywall.js # Paywall rendering
│ └── tracking.js # Analytics
│
└── examples/ # Usage Examples
├── basic-setup.js # Minimal setup
├── advanced-usage.js # Advanced features
└── test-without-supabase.js # Core testing
import React from 'react';
import { LightswitchProvider, ProtectedRoute } from 'lightswitch-js';
import { supabase } from './your-supabase-client';
const App = () => (
<LightswitchProvider
publishableKey="pk_your-app_your-key"
appSlug="your-app"
supabaseClient={supabase}
autoShowPaywall={true}
>
<BrowserRouter>
<Routes>
<Route path="/" element={<Landing />} />
<Route path="/app" element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
} />
</Routes>
</BrowserRouter>
</LightswitchProvider>
);
import { useLightswitch, useEntitlement } from 'lightswitch-js';
const MyComponent = () => {
const { showPaywall, redirectToLogin } = useLightswitch();
const { entitled, loading } = useEntitlement('has_access');
if (!entitled) {
return <button onClick={showPaywall}>Upgrade</button>;
}
return <div>Premium content!</div>;
};
LightswitchProviderMain provider that wraps your app and handles SDK initialization.
Props:
publishableKey (string) - Your app's publishable keyappSlug (string) - Your app slugsupabaseClient (optional) - Supabase client for auth integrationautoShowPaywall (boolean) - Auto-show paywall when not entitledProtectedRouteComponent that protects routes based on entitlements.
Props:
children (ReactNode) - Content to show when entitledfeature (string) - Feature to check (defaults to "has_access")useLightswitch()Main hook for SDK functionality.
Returns:
showPaywall() - Show paywall modalredirectToLogin() - Redirect to loginredirectToSignup() - Redirect to signupisInitialized - SDK initialization statususeEntitlement(feature, options)Hook for checking entitlements.
Parameters:
feature (string) - Feature to checkoptions.checkOnMount (boolean) - Check on component mountReturns:
entitled (boolean) - Whether user is entitledloading (boolean) - Loading stateerror (string) - Error message if anyuseLightswitchAuth()Hook for authentication state.
Returns:
isAuthenticated (boolean) - Auth statususer (object) - User infologout() - Logout functionsetSupabaseSession(token) - Set Supabase session from external tokenuseLightswitch().redirectToSignup()useLightswitch().redirectToLogin()useAuth.jsLightswitchProvideruseEntitlement hookshowPaywall() functiontrackEvent() functionSee the /examples folder for complete usage examples:
basic-setup.js - Minimal integrationadvanced-usage.js - Using hooks for controlexternal-auth-flow.js - Handle external auth flows (funnels)test-without-supabase.js - Core functionality testingThe SDK automatically handles external auth tokens (like from funnels) with zero additional code:
// That's it! The SDK handles everything automatically
<LightswitchProvider
publishableKey="pk_your-key"
appSlug="your-app"
supabaseClient={supabaseClient}
autoExternalAuth={true} // 👈 Default: true
>
<YourApp />
</LightswitchProvider>
What happens automatically:
?token=SUPABASE_TOKENIf you need custom control:
// Method 1: Using the hook
const { setSupabaseSession } = useLightswitch();
await setSupabaseSession(token);
// Method 2: Direct import
import { setSupabaseSession } from 'lightswitch-js';
await setSupabaseSession(token);
// Method 3: Complete control
import { handleExternalAuthReturn } from 'lightswitch-js';
await handleExternalAuthReturn({ redirectPath: '/dashboard' });
Allow users to manage their subscriptions, update payment methods, and view billing history through Stripe's customer portal.
The SDK automatically finds and binds to elements with the data-lightswitch-customer-portal attribute:
<!-- Simple portal button -->
<button data-lightswitch-customer-portal>Manage Billing</button>
<!-- With custom return URL -->
<button data-lightswitch-customer-portal="/dashboard">Account Settings</button>
<!-- Works on any clickable element -->
<a href="#" data-lightswitch-customer-portal="/account">Billing Portal</a>
import { useCustomerPortal } from 'lightswitch-js';
function AccountSettings() {
const { handleCustomerPortal, canAccessPortal } = useCustomerPortal();
if (!canAccessPortal) {
return <div>Please log in to manage billing.</div>;
}
return (
<button onClick={() => handleCustomerPortal('/dashboard')}>
Manage Billing
</button>
);
}
import Lightswitch from 'lightswitch-js';
// Redirect to customer portal
await Lightswitch.redirectToCustomerPortal('/dashboard');
// Or get portal URL for custom handling
const portalUrl = await Lightswitch.createCustomerPortal('/account');
window.open(portalUrl, '_blank');
The customer portal requires:
try {
await handleCustomerPortal('/dashboard');
} catch (error) {
if (error.message.includes('401')) {
// Redirect to login
} else if (error.message.includes('400')) {
// User needs to make a purchase first
}
}
The SDK is organized into three layers:
This structure makes it easy to understand, maintain, and extend the SDK while keeping the integration footprint minimal.
FAQs
A minimal SDK for subscription management, entitlements, and paywalls
We found that lightswitch-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.