Quickstart
Scaffold a working Base IdP app for any stack with one command.
The fastest way to get Base IdP running in your project is the scaffolder. You pick a stack, you paste your keys, and the CLI writes a starter that already works. No copy-pasting snippets out of a wiki. No guessing which env vars you need. The first time you run it should take about a minute.
This page walks through that minute, then explains what was generated so you can pick the file apart and adapt it.
Before you start
You need two things:
- A registered app. Open Square Experience Cloud, create an app, and copy the client id. If your app runs login on a server you also need the secret. See Create an App for the full flow.
- Node 20 or newer. The CLI ships with the TypeScript SDK and runs through
npx. There is nothing to install globally.
That is it. No other tooling, no extra accounts.
The one command
npx base-idp createRun it with no flags and the CLI prompts you for the stack, the client id, and a redirect URI. If you would rather skip the prompts, pass them inline:
npx base-idp create \
--stack flutter \
--client-id sq_live_yourapp \
--redirect-uri "myapp://auth/callback"For a confidential server you also pass the secret. Keep this command in your shell history rather than a Makefile if you want — the secret should never end up in version control.
npx base-idp create \
--stack nextjs-fullstack \
--client-id sq_live_web \
--client-secret sqk_your_secretListing every stack
If you are not sure which template fits, list them first.
npx base-idp create --listAvailable stacks:
flutter Flutter (mobile, public)
react-native React Native / Expo (mobile, public)
swiftui SwiftUI (iOS, public)
nextjs-fullstack Next.js fullstack (server login, confidential)
nextjs Next.js frontend (talks to a separate API, public)
nestjs NestJS (confidential server)
express Express / Node API (verify-only)
go Go API (verify-only)
rust Rust API (verify-only)Pick the one that matches your codebase. If you have a frontend and a backend in different languages, scaffold both.
What the CLI writes
Every stack produces the same shape: a .env (or platform-specific equivalent),
the SDK glue code wired to that env, and a BASE_IDP_SETUP.md with the three
remaining manual steps. Here is what comes out for Flutter, for example.
base-idp-flutter/
├── BASE_IDP_SETUP.md
├── lib/
│ └── auth/
│ └── base_idp_auth.dart
└── run.shimport 'package:base_idp/base_idp.dart';
class AppAuth {
AppAuth()
: _auth = BaseIdpFlutterAuth(
config: const BaseIdpConfig(
clientId: String.fromEnvironment('BASE_IDP_CLIENT_ID'),
),
redirectUri: 'myapp://auth/callback',
);
final BaseIdpFlutterAuth _auth;
Future<BaseIdpMobileSession> signIn() => _auth.login();
Map<String, dynamic> exchangePayload(BaseIdpMobileSession s) =>
s.toServerPayload().toJson();
}For a verify-only Go API the output is even smaller — no env file is required, because a verify-only backend needs nothing in env.
base-idp-go/
├── BASE_IDP_SETUP.md
├── .env # commented-out placeholder; nothing is required
└── auth/
└── baseidp.gopackage auth
import (
"net/http"
baseidp "github.com/squareexp/base-idp/sdk/go"
)
var client = baseidp.MustNew(baseidp.ConfigFromEnv())
func Protect(next http.Handler) http.Handler {
return client.RequireAuth(next, baseidp.MiddlewareOptions{})
}Wiring it into a real project
The generated directory is a reference, not a final layout. Move the file into
your app, point your build at it, and follow the three steps in the
BASE_IDP_SETUP.md. The steps differ by stack but always come down to:
- Install the SDK.
- Set the env value you got from the CLI.
- Register the redirect URI in the platform that needs it (iOS
Info.plist, Android manifest, Next.js route, and so on).
If you scaffolded into ./base-idp-flutter and your app is one level up:
mv base-idp-flutter/lib/auth/base_idp_auth.dart ./lib/auth/
cp base-idp-flutter/run.sh ./run.shThen update the redirect URI inside the Dart file and your platform manifests so they all match the one you registered. A mismatch here is the most common reason the browser opens and never returns.
Verifying the integration
Once the SDK is in place, check that your machine can actually reach Base IdP.
npx base-idp test --client-id sq_live_yourappTesting Base IdP connection to https://authlayer.squareexp.com...
healthz: 200 OK
discovery: 200 OK
client-config: 200 OK
IdP is reachable.Three green checks mean the network path is fine, your client id resolves, and your app's registration is active. If any line fails, you have a network or a client-id problem to fix before you debug your code.
What changed in your project
After you finish the setup steps you will have:
- One SDK in
package.json,pubspec.yaml,Cargo.toml, orgo.mod. - One env value (or none, for a verify-only backend).
- A login route, a callback route, or a guard — whichever fits your stack.
- A redirect URI registered both in your code and in your app registration.
Nothing else. There is no Base IdP-specific build step, no init script, no service to run. The SDK does its work at request time.