# Setup
URL: /docs/getting-started/setup
Source: /vercel/path0/docs/content/docs/(guides)/getting-started/setup.mdx
***
## title: Setup
### Prerequisites
Before getting started, make sure you have a project set up for your chosen platform:
* **Next.js**: A [Next.js project](https://nextjs.org/docs/getting-started/installation) using the app router (Stack Auth does not support the pages router on Next.js)
* **React**: A [React project](https://react.dev/learn/creating-a-react-app) (we show examples with Vite)
* **JavaScript**: A Node.js project with Express
* **Python**: A Python environment with your chosen framework (Django, FastAPI, or Flask)
We recommend using our **setup wizard** for JavaScript frameworks for a seamless installation experience. For Python, we recommend using the REST API approach.
### Setup Wizard / Manual Installation
Setup wizard (recommended for JS)
Manual installation
### Run installation wizard
The setup wizard is available for JavaScript/TypeScript frameworks. For Python projects, please use the manual installation method.
Run Stack's installation wizard with the following command:
```sh title="Terminal"
npx @stackframe/init-stack@latest
```
### Update API keys
Create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its environment variables into the appropriate configuration file:
**Next.js:**
```bash title=".env.local"
NEXT_PUBLIC_STACK_PROJECT_ID=
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=
STACK_SECRET_SERVER_KEY=
```
**React:**
```typescript title="stack/client.ts"
// Update the values in stack/client.ts created by the wizard
export const stackClientApp = new StackClientApp({
projectId: "your-project-id",
publishableClientKey: "your-publishable-client-key",
tokenStore: "cookie",
});
```
**Vanilla JavaScript:**
```bash title=".env"
STACK_PROJECT_ID=
STACK_PUBLISHABLE_CLIENT_KEY=
STACK_SECRET_SERVER_KEY=
```
### Done!
That's it! The wizard should have created or updated the following files in your project:
**For Next.js:**
* `app/handler/[...stack]/page.tsx`: Default pages for sign-in, sign-out, account settings, and more
* `app/layout.tsx`: Updated to wrap the entire body with `StackProvider` and `StackTheme`
* `app/loading.tsx`: Suspense boundary for Stack's async hooks
* `stack/server.ts`: Contains the `stackServerApp` for server-side usage
* `stack/client.ts`: Contains the `stackClientApp` for client-side usage
**For React:**
* `stack/client.ts`: Contains the `stackClientApp` configuration
* Your app should be wrapped with `StackProvider` and `StackTheme`
**For Node.js/Express:**
* `stack/server.ts`: Contains the `stackServerApp` configuration
Note: The setup wizard also supports existing, complicated projects. Cases where manual installation is necessary are rare for JavaScript frameworks.
### Install package
First, install the appropriate Stack package:
**Next.js:**
```bash title="Terminal"
npm install @stackframe/stack
```
**React:**
```bash title="Terminal"
npm install @stackframe/react
```
**Express:**
```bash title="Terminal"
npm install @stackframe/js
```
**Node.js:**
```bash title="Terminal"
npm install @stackframe/js
```
**Django:**
```bash title="Terminal"
pip install requests
```
**FastAPI:**
```bash title="Terminal"
pip install requests
```
**Flask:**
```bash title="Terminal"
pip install requests
```
### Create API keys
[Register a new account on Stack](https://app.stack-auth.com/handler/sign-up), create a project in the dashboard, create a new API key from the left sidebar, and copy the project ID, publishable client key, and secret server key.
### Configure environment variables
Set up your environment variables or configuration:
**Next.js:**
```bash title=".env.local"
NEXT_PUBLIC_STACK_PROJECT_ID=
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=
STACK_SECRET_SERVER_KEY=
```
**React:**
```bash title=".env"
# Store these in environment variables or directly in the client file during development
VITE_STACK_PROJECT_ID=
VITE_STACK_PUBLISHABLE_CLIENT_KEY=
```
**Express:**
```bash title=".env"
STACK_PROJECT_ID=
STACK_PUBLISHABLE_CLIENT_KEY=
STACK_SECRET_SERVER_KEY=
```
**Node.js:**
```bash title=".env"
STACK_PROJECT_ID=
STACK_PUBLISHABLE_CLIENT_KEY=
STACK_SECRET_SERVER_KEY=
```
**Django:**
```python title="settings.py"
import os
stack_project_id = os.getenv("STACK_PROJECT_ID")
stack_publishable_client_key = os.getenv("STACK_PUBLISHABLE_CLIENT_KEY")
stack_secret_server_key = os.getenv("STACK_SECRET_SERVER_KEY")
```
**FastAPI:**
```python title="main.py"
import os
stack_project_id = os.getenv("STACK_PROJECT_ID")
stack_publishable_client_key = os.getenv("STACK_PUBLISHABLE_CLIENT_KEY")
stack_secret_server_key = os.getenv("STACK_SECRET_SERVER_KEY")
```
**Flask:**
```python title="app.py"
import os
stack_project_id = os.getenv("STACK_PROJECT_ID")
stack_publishable_client_key = os.getenv("STACK_PUBLISHABLE_CLIENT_KEY")
stack_secret_server_key = os.getenv("STACK_SECRET_SERVER_KEY")
```
### Create Stack configuration
Create the Stack app configuration:
**stack/server.ts:**
```typescript title="stack/server.ts"
import "server-only";
import { StackServerApp } from "@stackframe/stack";
export const stackServerApp = new StackServerApp({
tokenStore: "nextjs-cookie", // storing auth tokens in cookies
});
```
**stack/client.ts:**
```typescript title="stack/client.ts"
import { StackClientApp } from "@stackframe/stack";
export const stackClientApp = new StackClientApp({
// Environment variables are automatically read
});
```
**stack/client.ts:**
```typescript title="stack/client.ts"
import { StackClientApp } from "@stackframe/react";
// If you use React Router, uncomment the next line and the redirectMethod below
// import { useNavigate } from "react-router-dom";
export const stackClientApp = new StackClientApp({
projectId: process.env.VITE_STACK_PROJECT_ID || "your-project-id",
publishableClientKey: process.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY || "your-publishable-client-key",
tokenStore: "cookie",
// redirectMethod: { useNavigate }, // Optional: only if using react-router-dom
});
```
**stack/server.ts:**
```typescript title="stack/server.ts"
import { StackServerApp } from "@stackframe/js";
export const stackServerApp = new StackServerApp({
projectId: process.env.STACK_PROJECT_ID,
publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY,
secretServerKey: process.env.STACK_SECRET_SERVER_KEY,
tokenStore: "memory",
});
```
**stack/client.ts:**
```typescript title="stack/client.ts"
import { StackClientApp } from "@stackframe/js";
export const stackClientApp = new StackClientApp({
projectId: process.env.STACK_PROJECT_ID,
publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY,
tokenStore: "cookie",
});
```
**stack/server.js:**
```javascript title="stack/server.js"
import { StackServerApp } from "@stackframe/js";
export const stackServerApp = new StackServerApp({
projectId: process.env.STACK_PROJECT_ID,
publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY,
secretServerKey: process.env.STACK_SECRET_SERVER_KEY,
tokenStore: "memory",
});
```
**stack/client.js:**
```javascript title="stack/client.js"
import { StackClientApp } from "@stackframe/js";
export const stackClientApp = new StackClientApp({
projectId: process.env.STACK_PROJECT_ID,
publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY,
tokenStore: "cookie",
});
```
**views.py:**
```python title="views.py"
import requests
def stack_auth_request(method, endpoint, **kwargs):
res = requests.request(
method,
f'https://api.stack-auth.com/{endpoint}',
headers={
'x-stack-access-type': 'server', # or 'client' if you're only accessing the client API
'x-stack-project-id': stack_project_id,
'x-stack-publishable-client-key': stack_publishable_client_key,
'x-stack-secret-server-key': stack_secret_server_key, # not necessary if access type is 'client'
**kwargs.pop('headers', {}),
},
**kwargs,
)
if res.status_code >= 400:
raise Exception(f"Stack Auth API request failed with {res.status_code}: {res.text}")
return res.json()
```
**main.py:**
```python title="main.py"
import requests
def stack_auth_request(method, endpoint, **kwargs):
res = requests.request(
method,
f'https://api.stack-auth.com/{endpoint}',
headers={
'x-stack-access-type': 'server', # or 'client' if you're only accessing the client API
'x-stack-project-id': stack_project_id,
'x-stack-publishable-client-key': stack_publishable_client_key,
'x-stack-secret-server-key': stack_secret_server_key, # not necessary if access type is 'client'
**kwargs.pop('headers', {}),
},
**kwargs,
)
if res.status_code >= 400:
raise Exception(f"Stack Auth API request failed with {res.status_code}: {res.text}")
return res.json()
```
**app.py:**
```python title="app.py"
import requests
def stack_auth_request(method, endpoint, **kwargs):
res = requests.request(
method,
f'https://api.stack-auth.com/{endpoint}',
headers={
'x-stack-access-type': 'server', # or 'client' if you're only accessing the client API
'x-stack-project-id': stack_project_id,
'x-stack-publishable-client-key': stack_publishable_client_key,
'x-stack-secret-server-key': stack_secret_server_key, # not necessary if access type is 'client'
**kwargs.pop('headers', {}),
},
**kwargs,
)
if res.status_code >= 400:
raise Exception(f"Stack Auth API request failed with {res.status_code}: {res.text}")
return res.json()
```
### Set up authentication handlers (Frontend frameworks only)
For JavaScript frameworks, create the authentication handler:
**Next.js:**
```typescript title="app/handler/[...stack]/page.tsx"
import { StackHandler } from "@stackframe/stack";
import { stackServerApp } from "@/stack/server";
export default function Handler(props: unknown) {
return ;
}
```
**React:**
```typescript title="App.tsx"
import { StackHandler, StackProvider, StackTheme } from "@stackframe/react";
import { Suspense } from "react";
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
import { stackClientApp } from "./stack/client";
function HandlerRoutes() {
const location = useLocation();
return (
);
}
export default function App() {
return (
} />
hello world} />
);
}
```
**Express:**
```typescript title="Note"
// Express doesn't use built-in handlers
// Use the REST API or integrate with your frontend
```
**Node.js:**
```javascript title="Note"
// Node.js doesn't use built-in handlers
// Use the REST API or integrate with your frontend
```
### Add providers (Next.js and React only)
For Next.js and React, wrap your app with Stack providers:
**Next.js:**
```typescript title="app/layout.tsx"
import React from "react";
import { StackProvider, StackTheme } from "@stackframe/stack";
import { stackServerApp } from "@/stack/server";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
**React:**
```typescript title="Note"
// Already shown in the App.tsx example above
// Make sure to wrap your app with StackProvider and StackTheme
```
### Add loading boundary (Next.js only)
For Next.js, add a Suspense boundary:
```typescript title="app/loading.tsx"
export default function Loading() {
// You can use any loading indicator here
return <>
Loading...
>;
}
```
### Add suspense boundary (React only)
For React, add a suspense boundary:
```typescript title="App.tsx"
import { Suspense } from "react";
import { StackProvider } from "@stackframe/react";
import { stackClientApp } from "./stack/client";
export default function App() {
return (
// Wrap your StackProvider with Suspense for async hooks to work
Loading...}>
{/* Your app content */}
);
}
```
### Done!
## Post-setup
That's it! Stack is now configured in your project.
### Testing your setup
**Next.js:**
```bash title="Terminal"
# Start your Next.js app
npm run dev
# Navigate to the sign-up page
# http://localhost:3000/handler/sign-up
```
**React:**
```bash title="Terminal"
# Start your React app
npm run dev
# Navigate to the sign-up page
# http://localhost:5173/handler/sign-up
```
**Express:**
```bash title="Terminal"
# Start your Express server
npm start
# Use the REST API or integrate with your frontend
# Check the REST API documentation for endpoints
```
**Node.js:**
```bash title="Terminal"
# Start your Node.js app
node index.js
# Use the REST API or integrate with your frontend
# Check the REST API documentation for endpoints
```
**Django:**
```python title="Terminal"
# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your Django server
python manage.py runserver
```
**FastAPI:**
```python title="Terminal"
# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your FastAPI server
uvicorn main:app --reload
```
**Flask:**
```python title="Terminal"
# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your Flask server
flask run
```
### What you'll see
For JavaScript frameworks with built-in UI components, you'll see the Stack Auth sign-up page:
After signing up/in, you will be redirected back to the home page. You can also check out the account settings page.
For Python and backend-only JavaScript setups, you'll interact with Stack Auth through the REST API.
## Example usage
Here are some basic usage examples for each platform:
**Server Component:**
```typescript title="Server Component"
import { stackServerApp } from "@/stack/server";
// In a Server Component or API route
const user = await stackServerApp.getUser();
if (user) {
console.log("User is signed in:", user.displayName);
} else {
console.log("User is not signed in");
}
```
**Client Component:**
```typescript title="Client Component"
'use client';
import { useUser } from "@stackframe/stack";
export default function MyComponent() {
const user = useUser();
if (user) {
return
Hello, {user.displayName}!
;
} else {
return Please sign in
;
}
}
```
**Component:**
```typescript title="Component"
import { useUser } from "@stackframe/react";
export default function MyComponent() {
const user = useUser();
if (user) {
return Hello, {user.displayName}!
;
} else {
return Please sign in
;
}
}
```
**server.ts:**
```typescript title="server.ts"
import { stackServerApp } from "./stack/server.js";
app.get('/profile', async (req, res) => {
try {
// Get access token from request headers
const accessToken = req.headers['x-stack-access-token'];
const user = await stackServerApp.getUser({ accessToken });
if (user) {
res.json({ message: `Hello, ${user.displayName}!` });
} else {
res.status(401).json({ error: 'Not authenticated' });
}
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
});
```
**index.js:**
```javascript title="index.js"
import { stackServerApp } from "./stack/server.js";
async function checkUser(accessToken) {
try {
const user = await stackServerApp.getUser({ accessToken });
if (user) {
console.log(`Hello, ${user.displayName}!`);
} else {
console.log('User not authenticated');
}
} catch (error) {
console.error('Error:', error);
}
}
```
**views.py:**
```python title="views.py"
# In your views.py
def profile_view(request):
# Get access token from request headers
access_token = request.headers.get('X-Stack-Access-Token')
try:
user_data = stack_auth_request('GET', '/api/v1/users/me', headers={
'x-stack-access-token': access_token,
})
return JsonResponse({'message': f"Hello, {user_data['displayName']}!"})
except Exception as e:
return JsonResponse({'error': 'Not authenticated'}, status=401)
```
**main.py:**
```python title="main.py"
from fastapi import FastAPI, Header, HTTPException
app = FastAPI()
@app.get("/profile")
async def get_profile(x_stack_access_token: str = Header(None)):
if not x_stack_access_token:
raise HTTPException(status_code=401, detail="Access token required")
try:
user_data = stack_auth_request('GET', '/api/v1/users/me', headers={
'x-stack-access-token': x_stack_access_token,
})
return {"message": f"Hello, {user_data['displayName']}!"}
except Exception as e:
raise HTTPException(status_code=401, detail="Not authenticated")
```
**app.py:**
```python title="app.py"
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/profile')
def profile():
access_token = request.headers.get('X-Stack-Access-Token')
if not access_token:
return jsonify({'error': 'Access token required'}), 401
try:
user_data = stack_auth_request('GET', '/api/v1/users/me', headers={
'x-stack-access-token': access_token,
})
return jsonify({'message': f"Hello, {user_data['displayName']}!"})
except Exception as e:
return jsonify({'error': 'Not authenticated'}), 401
```
## Next steps
Next up, we will show you how to [retrieve and update user information](./users.mdx), and how to [protect a page](./users.mdx#protecting-a-page) from unauthorized access.
For Python developers, check out the [REST API documentation](../rest-api/overview.mdx) to learn more about the available endpoints and how to use them in your Python application.