> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js Quickstart

> Add Bijection to a Next.js project

<Tip>
  **Bijection + Next.js**

  Bijection is an all-in-one backend and database that integrates quickly and easily
  with Next.js.

  Once you've gotten started, see how to set up
  [hosting](/production/hosting/hosting),
  [server rendering](/client/nextjs/app-router/server-rendering), and
  [auth](/client/nextjs/app-router/index).
</Tip>

Learn how to create a Next.js app (App Router) with a Bijection backend,
starting from the `nextjs` template of `bijection init`.

Alternatively see the
[Pages Router](/client/nextjs/pages-router/quickstart-nextjs-pages-router)
version of this quickstart.

<Steps>
  <Step title="Install the Bijection CLI">
    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    curl -fsSL https://bijection.com/install.sh | sh
    ```

    If `bijection` is not on your `PATH` afterwards, add it as the installer
    explains. See [Install Bijection](/get-started/install).
  </Step>

  <Step title="Create the app">
    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    bijection init my-app --template nextjs
    ```

    This writes a Next.js app and its Bijection backend into `my-app/`, then
    installs the app's dependencies, including the Bijection SDK, with your
    JavaScript package manager: the one of an enclosing workspace, otherwise
    the first of pnpm, bun, yarn and npm on your `PATH`. The app needs Node.js
    and one of them; the backend does not. Last, it generates
    `bijection/_generated/`, the typed API of your functions, so the project
    typechecks before it has a deployment.

    ```text theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    my-app/
    ├── app/
    │   ├── BijectionClientProvider.tsx   creates the Bijection client
    │   ├── layout.tsx                    wraps every page in it
    │   └── page.tsx                      the page that calls your functions
    ├── bijection/
    │   ├── _generated/                   the typed API of your functions
    │   ├── messages.ts                   a query and a mutation
    │   ├── schema.ts                     the messages table
    │   └── tsconfig.json
    ├── bijection.json
    ├── package.json
    └── tsconfig.json
    ```
  </Step>

  <Step title="Log in">
    Log this machine in to Bijection. You only do this once per machine.

    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    cd my-app
    bijection login
    ```

    <Note>
      Bijection's hosted service is not yet open for public sign-up, and the CLI
      has no default management service. Before running `bijection login`, set
      `BIJECTION_MANAGEMENT_URL` to the management service URL you were given, in
      your shell's startup file so that every later `bijection` command sees it too:

      ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      export BIJECTION_MANAGEMENT_URL=https://<your management service>
      ```
    </Note>
  </Step>

  <Step title="Start the backend">
    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    bijection dev
    ```

    The first run creates your dev deployment and writes its URL to
    `.env.local`, where the app reads it as `NEXT_PUBLIC_BIJECTION_URL`.
    `bijection dev` then keeps running: on every change it pushes `bijection/`
    to your dev deployment and regenerates `bijection/_generated/`. Keep it
    running.
  </Step>

  <Step title="Start the app">
    In another terminal, start the Next.js development server with the command
    `bijection init` printed for your package manager, for example:

    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    npm run dev
    ```

    Open [http://localhost:3000](http://localhost:3000) and send a message.
    Open a second window: messages appear in both as soon as they are sent.
  </Step>

  <Step title="Read the backend">
    `bijection/schema.ts` declares the `messages` table, and
    `bijection/messages.ts` exports a query and a mutation. Each export is an API
    function named after the file and the export: `api.messages.list` and
    `api.messages.send`.

    ```ts bijection/messages.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    import { v } from "bijection/values";
    import { mutation, query } from "./_generated/server";

    // The 50 most recent messages, newest first.
    export const list = query({
      args: {},
      handler: async (ctx) => {
        return await ctx.db.query("messages").order("desc").take(50);
      },
    });

    export const send = mutation({
      args: { author: v.string(), body: v.string() },
      handler: async (ctx, args) => {
        await ctx.db.insert("messages", args);
      },
    });
    ```
  </Step>

  <Step title="Read the app">
    `BijectionProvider` needs a `BijectionReactClient`, and both run in the
    browser, so `app/BijectionClientProvider.tsx` is a client component:

    ```tsx app/BijectionClientProvider.tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    "use client";

    import { BijectionProvider, BijectionReactClient } from "bijection/react";
    import { ReactNode } from "react";

    const client = new BijectionReactClient(process.env.NEXT_PUBLIC_BIJECTION_URL!);

    export function BijectionClientProvider({ children }: { children: ReactNode }) {
      return <BijectionProvider client={client}>{children}</BijectionProvider>;
    }
    ```

    `app/layout.tsx` wraps the `body` in `<BijectionClientProvider>`, and
    `app/page.tsx`, also a client component, subscribes to the query with
    `useQuery` and calls the mutation with `useMutation`. The query result
    updates by itself whenever the messages change:

    ```tsx app/page.tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    const messages = useQuery(api.messages.list);
    const send = useMutation(api.messages.send);
    ```
  </Step>

  <Step title="Call a function from the CLI">
    With the app open, send a message from another terminal. It appears in the
    app at once:

    ```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    bijection run messages:send '{"author": "me", "body": "Hello"}'
    ```
  </Step>
</Steps>

See the complete [Next.js documentation](/client/nextjs/app-router/index).
