Quickstart
Build your first Stacks app with wallet connectivity in 5 minutes
What you'll learn
In this quickstart, you'll build a simple web app that connects to a Stacks wallet and sends a transaction. By the end, you'll understand:
Prerequisites
Quickstart
Create a new Next.js app
Start by creating a new Next.js application with TypeScript:
$npx create-next-app@latest my-stacks-app --typescript --tailwind --app[32m✔[0m Would you like to use ESLint? … No / [1mYes[0m[32m✔[0m Would you like to use `src/` directory? … No / [1mYes[0m[32m✔[0m Would you like to customize the default import alias? … [1mNo[0m / Yes[32mCreating a new Next.js app in[0m [1m./my-stacks-app[0m
Navigate to your project directory:
$cd my-stacks-app
Install Stacks.js packages
Add the necessary Stacks.js packages to your project:
$npm install @stacks/connect @stacks/transactions @stacks/network[32madded[0m 47 packages in 3s
These packages provide:
@stacks/connect
- Wallet connection and transaction broadcasting@stacks/transactions
- Transaction building utilities@stacks/network
- Network configuration (mainnet/testnet)
Set up authentication
Create a new file for authentication setup:
import { AppConfig, UserSession } from '@stacks/connect';const appConfig = new AppConfig(['store_write', 'publish_data']);export const userSession = new UserSession({ appConfig });export const appDetails = {name: 'My Stacks App',icon: '/logo.png', // You can add a logo to your public folder};
The AppConfig
defines what permissions your app needs, and UserSession
manages the user's authentication state.
Create a wallet connection component
Replace the contents of your main page with a wallet connection interface:
'use client';import { useState, useEffect } from 'react';import { showConnect, showSTXTransfer } from '@stacks/connect';import { StacksTestnet } from '@stacks/network';import { AnchorMode } from '@stacks/transactions';import { userSession, appDetails } from './lib/auth';export default function Home() {const [mounted, setMounted] = useState(false);const [userData, setUserData] = useState<any>(null);useEffect(() => {setMounted(true);if (userSession.isUserSignedIn()) {setUserData(userSession.loadUserData());}}, []);const connectWallet = () => {showConnect({appDetails,onFinish: () => {setUserData(userSession.loadUserData());},userSession,});};const disconnectWallet = () => {userSession.signUserOut();setUserData(null);};const sendSTX = () => {showSTXTransfer({recipient: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM',amount: '1000000', // 1 STX in microSTXmemo: 'Hello from Stacks.js!',network: new StacksTestnet(),anchorMode: AnchorMode.Any,onFinish: (data) => {console.log('Transaction broadcast!', data);alert(`Transaction sent! ID: ${data.txId}`);},onCancel: () => {console.log('Transaction canceled');},});};if (!mounted) return null;return (<main className="flex min-h-screen flex-col items-center justify-center p-24"><div className="max-w-md w-full space-y-8"><h1 className="text-4xl font-bold text-center">My Stacks App</h1>{!userData ? (<buttononClick={connectWallet}className="w-full bg-blue-600 text-white py-3 px-6 rounded-lg hover:bg-blue-700">Connect Wallet</button>) : (<div className="space-y-4"><div className="bg-gray-100 p-4 rounded-lg"><p className="text-sm text-gray-600">Connected as:</p><p className="font-mono text-sm break-all">{userData.profile.stxAddress.testnet}</p></div><buttononClick={sendSTX}className="w-full bg-green-600 text-white py-3 px-6 rounded-lg hover:bg-green-700">Send 1 STX</button><buttononClick={disconnectWallet}className="w-full bg-red-600 text-white py-3 px-6 rounded-lg hover:bg-red-700">Disconnect</button></div>)}</div></main>);}
Run your app
Start the development server:
$npm run dev[32m▲ Next.js 14.0.0[0m[90m- Local:[0m http://localhost:3000
Open http://localhost:3000 in your browser. You should see:
- 1A "Connect Wallet" button
- 2After connecting, your testnet address
- 3A button to send 1 STX (testnet STX)
Make sure your wallet is set to testnet mode for this example. You can get free testnet STX from the Stacks faucet.
Understanding the code
Let's break down what's happening in the code:
Authentication setup
const appConfig = new AppConfig(['store_write', 'publish_data']);
This configures what permissions your app needs. Common scopes include:
store_write
- Store encrypted datapublish_data
- Publish data to Gaia storage
Wallet connection
showConnect({appDetails, // Your app's name and icononFinish: () => {// Called when user approves connection},userSession, // Manages authentication state});
The showConnect
function opens the wallet popup for users to approve the connection.
Sending transactions
showSTXTransfer({recipient: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM',amount: '1000000', // Amount in microSTXnetwork: new StacksTestnet(),anchorMode: AnchorMode.Any,onFinish: (data) => {// Called after user approves and broadcasts},});
This creates a STX transfer transaction and opens the wallet for user approval.
Next steps
Now that you have a working Stacks app, explore these topics: