Scheduler components and OAuth connection hooks for React
📖 Scheduler guide · 📚 API Reference · 🚀 Sign up · 💡 Samples · 💬 Forum
@nylas/react gives you Nylas Scheduler as React components, so you can drop a booking page or a full scheduling-page editor into your app instead of building availability logic, timezone handling, and booking forms yourself. It also ships a useNylasConnect hook and a NylasConnectButton for the OAuth flow that connects a user's calendar.
This repository is for contributors and anyone installing from source. If you just want to use the library in your app, head to the Scheduler guide on developer.nylas.com.
- Sign up for a free Nylas account and grab your client ID from the Nylas Dashboard.
- Register your app's callback URI under Hosted Authentication, so the connection flow is allowed to run.
- Install the package and render your first component — see below.
The Scheduler quickstart walks through a working setup end to end, with the finished code in quickstart-scheduler-react.
npm install @nylas/react@latest
# or
yarn add @nylas/react@latestThe package ships its own TypeScript types, and exposes three subpaths so you only bundle what you use:
| Import from | Contains |
|---|---|
@nylas/react |
Everything below except the Connect symbols |
@nylas/react/elements |
Scheduler and booking components |
@nylas/react/utils |
NylasIdentityRequestWrapper, and the LANGUAGE_CODE type |
@nylas/react/connect |
useNylasConnect, NylasConnectButton, and re-exports of @nylas/connect |
Note:
useNylasConnectandNylasConnectButtonare available only from@nylas/react/connect, not from the package root.
To install from source:
git clone https://github.com/nylas/javascript.git
cd javascript
pnpm installThree components are the entry points:
NylasScheduling— the booking page your end users see.NylasSchedulerEditor— the editor where your users build and configure scheduling pages.NylasSchedulingMethod— picks a scheduling method.
Around 50 further components (NylasAvailabilityPicker, NylasBookingForm, NylasBufferTime, NylasCancellationPolicy, NylasTimeslotPicker, and so on) are exported as the building blocks those two compose, alongside NylasNotetakerConfig and a set of form primitives and icons. Most apps only need the entry points.
The following example adds the Nylas Scheduler Editor and Scheduling components to your React app.
⚠️ Important: Make sure to replace theNYLAS_CLIENT_IDwith your Nylas Client ID. Your Nylas Client ID can be found in your app's Overview page on the Nylas Dashboard.
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
function App() {
// Get the configuration ID from the URL query string
const urlParams = new URLSearchParams(window.location.search);
const configId = urlParams.get("config_id") || "";
return (
<BrowserRouter>
<Routes>
<Route
path="/"
element={
<div>
<a href="/scheduler-editor" className="button">
View Scheduler Editor
</a>
<NylasScheduling
configurationId={configId}
schedulerApiUrl="https://api.us.nylas.com"
/>
</div>
}
/>
<Route
path="/scheduler-editor"
element={
<div>
<NylasSchedulerEditor
schedulerPreviewLink={`${window.location.origin}/?config_id=${config.id}`}
nylasSessionsConfig={{
clientId: "NYLAS_CLIENT_ID", // Replace with your Nylas client ID from the previous
redirectUri: `${window.location.origin}/scheduler-editor`,
domain: "https://api.us.nylas.com/v3", // or 'https://api.eu.nylas.com/v3' for EU data center
hosted: true,
accessType: "offline",
}}
defaultSchedulerConfigState={{
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
scheduler: {
// The callback URLs to be set in email notifications
rescheduling_url: `${window.location.origin}/reschedule/:booking_ref`, // The URL of the email notification includes the booking reference
cancellation_url: `${window.location.origin}/cancel/:booking_ref`,
},
},
}}
/>
</div>
}
/>
</Routes>
</BrowserRouter>
);
}
export default App;To create a Scheduling Page from the Scheduler Editor, you'll need a working Scheduler UI. To do this, run a local server to host your Scheduler Editor and Scheduling Pages.
Navigate to the root directory of your project and run the following command.
npm run dev -- --port <PORT>
After you run the command, open your browser to http://localhost:<PORT>/scheduler-editor to see your Scheduler Editor and create your first Scheduling Page.
The useNylasConnect hook provides a simple way to add OAuth authentication to your React app using Nylas Connect.
import { useNylasConnect } from "@nylas/react/connect";
function LoginButton() {
const { isConnected, connect, logout, grant, isLoading } = useNylasConnect({
clientId: "your-nylas-client-id",
redirectUri: "http://localhost:3000/callback",
});
if (isLoading) return <div>Loading...</div>;
if (isConnected) {
return (
<div>
<p>Connected as: {grant?.email}</p>
<button onClick={() => logout()}>Logout</button>
</div>
);
}
return (
<button onClick={() => connect({ method: "popup" })}>Connect Account</button>
);
}UseNylasConnectConfig extends ConnectConfig from @nylas/connect, so every option there — apiUrl, defaultScopes, persistTokens, logLevel, codeExchange, identityProviderToken, and the rest — is accepted here too. The most common, plus the four the hook adds of its own:
| Option | Type | Default | Description |
|---|---|---|---|
clientId |
string |
NYLAS_CLIENT_ID |
Your Nylas Client ID |
redirectUri |
string |
NYLAS_REDIRECT_URI |
OAuth callback URL |
autoHandleCallback |
boolean |
true |
Automatically handle the OAuth callback |
autoRefreshInterval |
number |
disabled | Auto-refresh session interval, in ms |
initialLoadingState |
boolean |
true |
Loading state the hook mounts with |
retryAttempts |
number |
0 |
Retry attempts for failed operations |
enableAutoRecovery |
boolean |
false |
Automatic recovery from network errors |
State:
isConnected— whether the user is authenticatedgrant— the current user'sGrantInfo, ornullisLoading— loading state for operationserror— current error, if any
Actions:
connect(options)— start the OAuth flowlogout(grantId?)— sign the user outrefreshSession()— refresh the current sessionsubscribe(callback)— listen to connection eventssetLogLevel(level)— change log verbosity at runtime
The underlying client is also returned as connectClient, for anything the hook doesn't wrap.
For security, use environment variables for your configuration:
# .env.local
VITE_NYLAS_CLIENT_ID=your-nylas-client-id
VITE_NYLAS_REDIRECT_URI=http://localhost:3000/callbackconst { isConnected, connect } = useNylasConnect({
clientId: import.meta.env.VITE_NYLAS_CLIENT_ID,
redirectUri: import.meta.env.VITE_NYLAS_REDIRECT_URI,
});Next.js uses NEXT_PUBLIC_ instead of VITE_.
The NylasConnectButton component provides a simple way to add email provider authentication to your React application.
import { NylasConnectButton } from "@nylas/react/connect";
function App() {
return (
<NylasConnectButton
clientId="your-nylas-client-id"
redirectUri="http://localhost:3000/callback"
onSuccess={(result) => {
console.log("Connected successfully:", result);
}}
onError={(error) => {
console.error("Connection failed:", error);
}}
/>
);
}Beyond clientId and redirectUri, the props fall into four groups:
| Group | Props |
|---|---|
| Connection | apiUrl, defaultScopes, persistTokens, method, provider, scopes, loginHint, popupWidth, popupHeight |
| Appearance | text, children, variant (primary | outline), size (sm | md | lg), className, style, disabled, unstyled, cssVars |
| Callbacks | onStart, onSuccess, onError, onCancel |
| Advanced | identityProviderToken, codeExchange |
unstyled drops the default styling entirely; cssVars re-themes it without doing so, accepting --nylas-btn-bg, --nylas-btn-fg, --nylas-btn-border, and --nylas-btn-bg-hover.
For applications that use external identity providers (via JWKS), you can pass identity provider tokens during authentication:
import { NylasConnectButton } from "@nylas/react/connect";
function App() {
// Function to retrieve JWT token from your external identity provider
const getIdpToken = async () => {
// Get the JWT token from your authentication system
const token = await yourAuthSystem.getJWT();
return token; // or return null if not available
};
return (
<NylasConnectButton
clientId="your-nylas-client-id"
redirectUri="http://localhost:3000/callback"
identityProviderToken={getIdpToken}
onSuccess={(result) => {
console.log("Connected with IDP claims:", result);
}}
onError={(error) => {
console.error("Connection failed:", error);
}}
/>
);
}Returning null continues without IDP claims; throwing fails authentication. Per-provider setup guides for Auth0, Clerk, Google, and WorkOS: external identity providers.
For enhanced security, you can handle the OAuth code exchange on your backend:
import { NylasConnectButton } from "@nylas/react/connect";
function App() {
const handleCodeExchange = async (params) => {
// Send the authorization code to your backend
const response = await fetch("/api/auth/exchange", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code: params.code,
state: params.state,
clientId: params.clientId,
redirectUri: params.redirectUri,
scopes: params.scopes,
provider: params.provider,
}),
});
if (!response.ok) {
throw new Error(`Token exchange failed: ${response.statusText}`);
}
const tokenData = await response.json();
// Return the expected ConnectResult format
return {
accessToken: tokenData.access_token,
idToken: tokenData.id_token,
grantId: tokenData.grant_id,
expiresAt: Date.now() + tokenData.expires_in * 1000,
scope: tokenData.scope,
grantInfo: tokenData.grant_info,
};
};
return (
<NylasConnectButton
clientId="your-nylas-client-id"
redirectUri="http://localhost:3000/callback"
codeExchange={handleCodeExchange}
onSuccess={(result) => {
console.log("Connected successfully:", result);
}}
onError={(error) => {
console.error("Connection failed:", error);
}}
/>
);
}The hook surfaces failures on error rather than throwing, so render from it directly. NylasConnectButton reports them through onError, and onCancel fires separately when the user closes the popup.
const { error, connect } = useNylasConnect({ clientId, redirectUri });
if (error) return <p role="alert">Couldn't connect: {error.message}</p>;Every error extends NylasConnectError and sets a distinct name — PopupError for a blocked or closed popup, ConfigError for a missing clientId, OAuthError when the provider rejects the request. All of them are re-exported from @nylas/react/connect.
- quickstart-scheduler-react — the finished code for the Scheduler quickstart.
- nylas-samples — full sample apps and product quickstarts.
nylas/skills drops Nylas into Claude Code, Cursor, Codex, and other agents that support the skills format:
npx skills add nylas/skills
/plugin marketplace add nylas/skills # Claude Code- Scheduler guide: developer.nylas.com/docs/v3/scheduler
- Scheduler quickstart: developer.nylas.com/docs/v3/getting-started/scheduler
- Scheduler API reference: developer.nylas.com/docs/api/v3/scheduler
- React connect guide: developer.nylas.com/docs/v3/auth/nylas-connect-react
useNylasConnectreference: every option and return valueNylasConnectButtonreference: every prop- Identity provider guides: Auth0, Clerk, Google, WorkOS
- Developer forum: forums.nylas.com
- Changelog: CHANGELOG.md
See CHANGELOG.md for per-release notes.
Issues, ideas, and pull requests welcome — see CONTRIBUTING.md. Before opening a large change, please open an issue or post in the forum so we can sanity-check the direction.
Found a vulnerability? Please don't open a public issue. Report it through our Vulnerability Disclosure Policy.
- @nylas/connect ·
npm install @nylas/connect - nylas-nodejs ·
npm install nylas - nylas-python ·
pip install nylas - nylas-ruby ·
gem install nylas - nylas-java · Maven / Gradle (Kotlin too)
MIT — see LICENSE.md.