Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/linter.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ jobs:
- name: Install Dependencies
run: cd template && pnpm install

- name: Generate Content Collections
if: inputs.component == 'template/web'
run: cd template && pnpm --filter web run content-collections:build

- name: Run Linters
uses: wearerequired/lint-action@v2
with:
Expand Down
8 changes: 8 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@
},
"packages/create-ship-app"
]
},
{
"group": "Plugins",
"pages": [
"plugins/overview",
"plugins/stripe-subscriptions",
"plugins/ai-chat"
]
}
]
}
Expand Down
18 changes: 17 additions & 1 deletion docs/packages/create-ship-app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,20 @@ or

```shell
npx create-ship-app@latest my-project
```
```

## Plugins

The CLI also supports installing pre-built features via the plugin system:

```shell
npx create-ship-app@latest install <plugin-name>
```

For example:

```shell
npx create-ship-app@latest install stripe-subscriptions
```

See the [Plugins documentation](/plugins/overview) for the full list of available plugins and how they work.
88 changes: 88 additions & 0 deletions docs/plugins/ai-chat.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: "AI Chat"
---

The `ai-chat` plugin adds an AI-powered chat interface to your Ship project. It features real-time streaming responses using Google Gemini, persistent chat history stored in MongoDB, and a polished chat UI with multiple conversation support.

## Installation

```shell
npx create-ship-app@latest install ai-chat
```

## What gets installed

### Dependencies

| Workspace | Package | Version |
|---|---|---|
| `apps/api` | `@ai-sdk/google` | `3.0.29` |
| `apps/api` | `ai` | `6.0.86` |
| `apps/web` | `@ai-sdk/react` | `3.0.88` |

### Files

**API (`apps/api`):**

| File | Description |
|---|---|
| `src/config/ai.config.ts` | Environment config for `GOOGLE_GENERATIVE_AI_API_KEY` |
| `src/services/ai/ai.service.ts` | AI service using Google Gemini (`gemini-2.5-flash`) with streaming support |
| `src/resources/ai-chat/ai-chat.schema.ts` | Zod schema for chat conversations |
| `src/resources/ai-chat/ai-chat.service.ts` | Database service for chat CRUD operations |
| `src/resources/ai-chat/ai-message.schema.ts` | Zod schema for individual messages (role, content) |
| `src/resources/ai-chat/ai-message.service.ts` | Database service for message CRUD operations |
| `src/resources/ai-chat/endpoints/create.ts` | Create a new chat conversation |
| `src/resources/ai-chat/endpoints/list.ts` | List all chats for the current user |
| `src/resources/ai-chat/endpoints/delete.ts` | Delete a chat and its messages |
| `src/resources/ai-chat/endpoints/get-messages.ts` | Get all messages in a chat |
| `src/resources/ai-chat/endpoints/send-message.ts` | Send a message and stream the AI response via SSE |
| `src/resources/ai-chat/index.ts` | Barrel export for services |

**Web (`apps/web`):**

| File | Description |
|---|---|
| `src/components/ui/prompt-input.tsx` | Reusable prompt input component with auto-resize and keyboard shortcuts |
| `src/pages/ai-chat/index.page.tsx` | Main AI chat page with conversation sidebar |
| `src/pages/ai-chat/[chatId].page.tsx` | Individual chat page (route handler) |
| `src/pages/ai-chat/components/AiChatBox.tsx` | Chat container with message list and input |
| `src/pages/ai-chat/components/AiChatInput.tsx` | Chat input with send button |
| `src/pages/ai-chat/components/AiChatMessage.tsx` | Individual message bubble (user/assistant) |
| `src/pages/ai-chat/components/AiMessageSkeleton.tsx` | Loading skeleton for messages |
| `src/pages/ai-chat/hooks/useAiChatManager.ts` | Hook managing chat state, SSE streaming, and message history |

## Environment variables

### API (`apps/api`)

| Variable | Description |
|---|---|
| `GOOGLE_GENERATIVE_AI_API_KEY` | Google AI API key from [Google AI Studio](https://aistudio.google.com/apikey) |

## How it works

### Streaming responses

The plugin uses **Server-Sent Events (SSE)** for real-time AI response streaming:

1. The user sends a message via `POST /:chatId/messages`.
2. The API saves the user message, loads the full conversation history, and calls Google Gemini.
3. The response is streamed back chunk by chunk as SSE events.
4. Once complete, the assistant message is saved to the database.

The frontend `useAiChatManager` hook handles parsing the SSE stream and updating the UI in real time.

### Chat management

Each user can have multiple chat conversations. Chats are automatically titled based on the first message. All data is stored in MongoDB via Ship's data service layer.

## API endpoints

| Method | Path | Description |
|---|---|---|
| `GET` | `/ai-chat/` | List all chats for the current user |
| `POST` | `/ai-chat/` | Create a new chat |
| `DELETE` | `/ai-chat/:chatId` | Delete a chat and its messages |
| `GET` | `/ai-chat/:chatId/messages` | Get messages for a chat |
| `POST` | `/ai-chat/:chatId/messages` | Send a message and stream AI response |
83 changes: 83 additions & 0 deletions docs/plugins/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: "Overview"
---

Plugins are pre-built features that can be installed into your Ship project with a single command. They add new functionality by scaffolding files across your monorepo (`apps/api`, `apps/web`, `packages/shared`) and merging the required dependencies into the respective `package.json` files.

Plugins are hosted in the public [ship-plugins](https://github.com/paralect/ship-plugins) repository and installed via the `create-ship-app` CLI.

## Installing a plugin

Run the following command from your project root:

```shell
npx create-ship-app@latest install <plugin-name>
```

For example:

```shell
npx create-ship-app@latest install stripe-subscriptions
```

The install process will:

1. **Download** the plugin files from the [ship-plugins](https://github.com/paralect/ship-plugins) repository.
2. **Copy files** into your project, preserving the directory structure. Existing files are never overwritten.
3. **Merge dependencies** declared in the plugin manifest into the appropriate workspace `package.json` files.
4. **Run post-install** — executes `pnpm install` and `pnpm run --filter shared generate` to install new dependencies and regenerate shared schemas.

## Available plugins

| Plugin | Description |
|---|---|
| [stripe-subscriptions](/plugins/stripe-subscriptions) | Subscription billing with Stripe Checkout, webhooks, and a pricing page |
| [ai-chat](/plugins/ai-chat) | AI chat with streaming responses powered by Google Gemini |

## Plugin structure

Each plugin in the [ship-plugins](https://github.com/paralect/ship-plugins) repository follows the same convention:

```
<plugin-name>/
├── package.json # Plugin manifest (name, version, dependencies)
└── apps/
├── api/ # API-side files (configs, resources, services)
└── web/ # Web-side files (pages, components, configs)
```

The `package.json` manifest declares which npm packages should be added to which workspace. For example:

```json
{
"name": "ship-plugin-stripe-subscriptions",
"version": "1.0.0",
"private": true,
"dependencies": {
"apps/api": {
"stripe": "20.3.1"
}
}
}
```

This tells the installer to add `stripe@20.3.1` to `apps/api/package.json`.

## Creating a plugin

Ship also provides a command to package your own feature as a plugin from the last git commit:

```shell
npx create-ship-app@latest create-plugin <plugin-name>
```

This will:

1. Extract new files added in the last commit.
2. Detect dependency changes from modified workspace `package.json` files.
3. Package everything into the plugin format.
4. Push to a new branch on the [ship-plugins](https://github.com/paralect/ship-plugins) repository and provide a PR link.

<Note>
You need push access to the [ship-plugins](https://github.com/paralect/ship-plugins) repository to use `create-plugin`.
</Note>
101 changes: 101 additions & 0 deletions docs/plugins/stripe-subscriptions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
title: "Stripe Subscriptions"
---

The `stripe-subscriptions` plugin adds subscription-based billing to your Ship project using [Stripe](https://stripe.com). It includes a complete pricing page, Stripe Checkout integration, webhook handling, and subscription management APIs.

## Installation

```shell
npx create-ship-app@latest install stripe-subscriptions
```

## What gets installed

### Dependencies

| Workspace | Package | Version |
|---|---|---|
| `apps/api` | `stripe` | `20.3.1` |

### Files

**API (`apps/api`):**

| File | Description |
|---|---|
| `src/config/stripe.config.ts` | Environment config for `STRIPE_SECRET_KEY` and `STRIPE_WEBHOOK_SECRET` |
| `src/services/stripe/stripe.service.ts` | Stripe SDK wrapper — customer creation, subscription helpers, billing portal access |
| `src/resources/subscriptions/subscription.schema.ts` | Zod schema for subscription data |
| `src/resources/subscriptions/endpoints/subscribe.ts` | Creates a Stripe Checkout session for new subscriptions |
| `src/resources/subscriptions/endpoints/getCurrent.ts` | Returns the current user's active subscription with live Stripe sync |
| `src/resources/subscriptions/endpoints/upgrade.ts` | Upgrades/downgrades/cancels the current subscription |
| `src/resources/subscriptions/endpoints/previewUpgrade.ts` | Previews proration costs before upgrading |
| `src/resources/subscriptions/endpoints/createPortalSession.ts` | Creates a Stripe Billing Portal session |
| `src/resources/webhook/endpoints/stripe.ts` | Handles Stripe webhook events (subscription created/updated/deleted) |
| `src/resources/users/user.stripe.extend.ts` | Extends the user schema with `stripeId` and `subscription` fields |

**Web (`apps/web`):**

| File | Description |
|---|---|
| `src/config/stripe.config.ts` | Client-side config for Stripe public key and price IDs |
| `src/pages/pricing/constants.ts` | Plan definitions (Free, Creator, Pro) with price IDs |
| `src/pages/pricing/index.page.tsx` | Full pricing page with plan selection, subscribe, upgrade, and billing portal |

## Environment variables

After installing, add the following environment variables:

### API (`apps/api`)

| Variable | Description |
|---|---|
| `STRIPE_SECRET_KEY` | Your Stripe secret key from the [Developers dashboard](https://dashboard.stripe.com/test/developers) |
| `STRIPE_WEBHOOK_SECRET` | Webhook signing secret from your Stripe webhook endpoint |

### Web (`apps/web`)

| Variable | Description |
|---|---|
| `NEXT_PUBLIC_STRIPE_PUBLIC_KEY` | Your Stripe publishable key |
| `NEXT_PUBLIC_PRICE_CREATOR` | Stripe Price ID for the Creator plan |
| `NEXT_PUBLIC_PRICE_PRO` | Stripe Price ID for the Pro plan |

## Stripe setup

### 1. Get API keys

Navigate to the [Developers](https://dashboard.stripe.com/test/developers) tab and select **API keys**.

- **Publishable key** → `NEXT_PUBLIC_STRIPE_PUBLIC_KEY` (web)
- **Secret key** → `STRIPE_SECRET_KEY` (api)

### 2. Create subscription products

Go to the [Products](https://dashboard.stripe.com/test/products) tab and create your subscription products. Each product needs a recurring price. Copy the Price IDs into your web environment variables.

### 3. Set up webhooks

Create a webhook endpoint pointing to `https://<your-api-url>/webhook/stripe` with the following events:

- `customer.subscription.created`
- `customer.subscription.updated`
- `customer.subscription.deleted`

Copy the webhook signing secret into `STRIPE_WEBHOOK_SECRET`.

<Tip>
For local development, use the [Stripe CLI](https://stripe.com/docs/stripe-cli) to forward webhook events to your localhost.
</Tip>

## API endpoints

| Method | Path | Description |
|---|---|---|
| `POST` | `/subscriptions/subscribe` | Create a Checkout session for a new subscription |
| `GET` | `/subscriptions/current` | Get the current user's subscription (syncs with Stripe) |
| `POST` | `/subscriptions/upgrade` | Change plan or cancel subscription |
| `GET` | `/subscriptions/preview-upgrade` | Preview proration costs |
| `POST` | `/subscriptions/create-portal-session` | Open the Stripe Billing Portal |
| `POST` | `/webhook/stripe` | Stripe webhook handler (public endpoint) |
40 changes: 29 additions & 11 deletions packages/create-ship-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@

The [Ship](https://ship.paralect.com) is a toolkit for makers to **ship** better products faster 🚀.

It is based on several open-source components, resulting from years of hard work [Paralect](https://www.paralect.com) team. We carefully select, document, and share our production-ready knowledge with you. Our technological choices are based on the following main tools: [Next.js](https://nextjs.org/), [React Query](https://react-query.tanstack.com/), [React Hook Form](https://react-hook-form.com/), [Mantine UI](https://mantine.dev/), [Koa.js](https://koajs.com/), [Socket.IO](https://socket.io/), [MongoDB](https://www.mongodb.com/), [Turborepo](https://turbo.build/repo/docs), [Docker](https://www.docker.com/), [Kubernetes](https://kubernetes.io/), [GitHub Actions](https://github.com/features/actions) and [TypeScript](https://www.typescriptlang.org/).
It is based on several open-source components, resulting from years of hard work by the [Paralect](https://www.paralect.com) team. We carefully select, document, and share our production-ready knowledge with you. Our technological choices are based on the following main tools: [Next.js](https://nextjs.org/), [Tanstack Query](https://tanstack.com/query/latest/), [React Hook Form](https://react-hook-form.com/), [Tailwind CSS](https://tailwindcss.com/), [shadcn/ui](https://ui.shadcn.com/), [Koa.js](https://koajs.com/), [Socket.IO](https://socket.io/), [MongoDB](https://www.mongodb.com/), [Turborepo](https://turbo.build/repo/docs), [Docker](https://www.docker.com/), [Kubernetes](https://kubernetes.io/), [GitHub Actions](https://github.com/features/actions) and [TypeScript](https://www.typescriptlang.org/).

We encourage developers to share production-ready solutions and help business ship something people need as quickly as possible.
We encourage developers to share production-ready solutions and help businesses ship something people need as quickly as possible.

## Features

- Full-stack boilerplate tested on production projects 🔥
- Customizable UI 🧱
- Email/password and Google Oauth authentication 🔐
- Customizable UI with [shadcn/ui](https://ui.shadcn.com/) and [Tailwind CSS](https://tailwindcss.com/) 🧱
- Email/password and Google OAuth authentication 🔐
- Plugin system — install pre-built features with a single command 🔌
- Multiple environments support 📝
- Reactive MongoDB [configuration](https://ship.paralect.com/docs/packages/node-mongo) with CUD events publishing 🍃
- [Kubernetes](https://ship.paralect.com/docs/deployment/kubernetes/overview) and [DO Apps](https://ship.paralect.com/docs/deployment/digital-ocean-apps) deployment for AWS and Digital Ocean platforms ☁
Expand All @@ -38,21 +39,38 @@ We encourage developers to share production-ready solutions and help business sh
npx create-ship-app@latest init
```

## [Documentation](https://ship.paralect.com/docs/intro)
## Plugins

Extend your project with pre-built features using the plugin system:

```shell
npx create-ship-app@latest install <plugin-name>
```

Available plugins:

| Plugin | Description |
|---|---|
| `stripe-subscriptions` | Subscription billing with Stripe Checkout, webhooks, and a pricing page |
| `ai-chat` | AI chat with streaming responses powered by Google Gemini |

See the [Plugins documentation](https://ship.paralect.com/docs/plugins/overview) for details.

## [Documentation](https://ship.paralect.com/docs/introduction)

## Why Ship?

Shipping is crucial part of any new product. The quicker you ship, the more time you have to validate your hypotheses. The quicker you validate your idea, the sooner you know if you're building what people want.
Shipping is a crucial part of any new product. The quicker you ship, the more time you have to validate your hypotheses. The quicker you validate your idea, the sooner you know if you're building what people want.

In the rush, developers often ignore quality. Backups, monitoring, proper data validation and many other things seems not so important in the beginning. Sometimes you're lucky, sometimes not.
In the rush, developers often ignore quality. Backups, monitoring, proper data validation and many other things seem not so important in the beginning. Sometimes you're lucky, sometimes not.

We believe we could ship great products faster, while maintain decent quality and have a plan for scaling when hypotheses where right.
We believe we could ship great products faster, while maintaining decent quality and have a plan for scaling when hypotheses are right.

## Core concepts

- We automatically build ship out of the number of smaller components. Our ultimate goal is too keep only parts your need for your product development.
- Every component is kept is tiny as possible to simplify maintenance and stay up to date with new releases.
- Ship is always in a production-ready state. We test every release manually to make sure great developer experience. We use ship to build our products, see more [here](https://www.paralect.com/build-stage).
- We automatically build Ship out of a number of smaller components. Our ultimate goal is to keep only the parts you need for your product development.
- Every component is kept as tiny as possible to simplify maintenance and stay up to date with new releases.
- Ship is always in a production-ready state. We test every release manually to make sure of a great developer experience. We use Ship to build our products, see more [here](https://www.paralect.com/build-stage).

## License

Expand Down
Loading
Loading