Skip to content

Open for Discussion: Add-Ons POC #492

Open
@ahaywood

Description

@ahaywood

At Redwood, we want to create an ecosystem of Add Ons or Shareware for your project. These can be as "simple" a single helper component or as a complex as an entire application.

Imagine starting a new project, and running a couple of commands -- you have a blog and newsletter ready to go, enabling you to focus on the business logic, essential to your application.

Just like shadcn/ui places your component code directly within your application, a RWSDK Add On's code lives directly in your application, completely yours, ready to be customized.

I created a Loom Video, explaining the current POC:
https://www.loom.com/share/6939da219a024aa088a56e46fee9c701

Here's the generated addon.jsonc file referenced with the video:

// addon.jsonc
{
  "name": "suggest",
  "description": "suggest add-on for RWSDK",
  "version": "0.1.0",
  "routes": {
    "file": "routes.ts",
    "prefix": ""
  },
  "packages": [
    "@radix-ui"
  ],
  "env": [
    "RESEND_API_KEY"
  ],
  "shadcn": {
    "required": true,
    "components": [
      "button",
      "input",
      "separator",
      "badge",
      "alert-dialog",
      "dialog",
      "label",
      "textarea",
      "checkbox",
      "switch",
      "dropdown-menu"
    ]
  },
  "tailwindcss": {
    "required": true
  },
  "styles": {
    "source": "src/app/addons/suggest/styles.css",
    "injectInto": "src/app/styles.css", // project-wide styles file,
    "injectDirective": "@import './addons/suggest/styles.css';"
  },
  "postInstallMessage": "✅ suggest add-on installed successfully."
}

README for how the Generate addon.jsonc file works

This document explains the generateAddonConfig.mjs script, which automatically analyzes an addon's content and generates the addon.jsonc configuration file.

Overview

The generateAddonConfig.mjs script scans your addon's codebase to detect:

  • Package dependencies
  • Environment variables
  • CSS files
  • Route files
  • ShadCN UI components

Based on this analysis, it generates an addon.jsonc file that describes your addon's requirements and configuration.

Usage

node src/scripts/generateAddonConfig.mjs <addon-name>

Where <addon-name> is the name of your addon (e.g., "suggest").

Generated Configuration

The script generates an addon.jsonc file with the following sections:

Basic Information

{
  "name": "your-addon-name",
  "description": "your-addon-name add-on for RWSDK",
  "version": "0.1.0"
}

Routes

If your addon includes a routes file (routes.ts, routes.tsx, routes.js, or routes.jsx), the script will detect it and add:

"routes": {
  "file": "routes.ts",
  "prefix": "/your-prefix"
}

The prefix is extracted from your routes file.

Packages

The script analyzes all JavaScript/TypeScript files to find external package dependencies:

"packages": [
  "package-name-1",
  "package-name-2"
]

Note: The script filters out common packages and those that are already part of RedwoodSDK.

Environment Variables

If your addon includes an env.example file, the script will extract environment variables:

"env": [
  "API_KEY",
  "SECRET_TOKEN"
]

Tailwind CSS

The script automatically detects if your addon requires Tailwind CSS:

"tailwindcss": {
  "required": true
}

Tailwind is detected as required if:

  • Your addon uses ShadCN UI components (which always require Tailwind)
  • Your CSS files contain @apply directives (which are Tailwind-specific)

ShadCN Components

The script detects ShadCN UI components used in your addon:

"shadcn": {
  "required": true,
  "components": [
    "button",
    "input",
    "dialog",
    "dropdown-menu"
  ]
}

ShadCN components are detected by analyzing:

  • Import statements with paths containing components/ui/
  • Import statements with paths containing @/components/ui/ or @/app/components/ui/
  • Relative imports with ./components/ui/ or ../components/ui/
  • Direct JSX usage of component names

Note: When ShadCN components are detected, Tailwind CSS is automatically marked as required.

Styles

If your addon includes CSS files, the script will add:

"styles": {
  "source": "src/app/addons/your-addon/styles.css",
  "injectInto": "src/app/styles.css",
  "injectDirective": "@import './addons/your-addon/styles.css';"
}

Post-Install Message

"postInstallMessage": "✅ your-addon add-on installed successfully."

Advanced Configuration

ShadCN Component Detection

The script detects ShadCN components by:

  1. Checking if a components/ui directory exists in the project
  2. Finding all available ShadCN components in that directory
  3. Scanning all JS/TS files in your addon for imports of these components
  4. Checking for direct JSX usage of these components

The script uses multiple detection methods to ensure it catches all component usages:

  • Regular expression matching for import statements
  • Line-by-line analysis for complex import patterns
  • JSX element detection

Package Filtering

The script filters out unnecessary packages to keep your addon's dependencies minimal:

  • Common packages already included in RedwoodSDK
  • Packages that are part of the ShadCN UI ecosystem when ShadCN is detected

Troubleshooting

If your addon's configuration is not generated correctly:

  1. Missing ShadCN Components: Make sure your imports use one of the supported path formats:

    • @/app/components/ui/component-name
    • @/components/ui/component-name
    • ./components/ui/component-name
    • ../components/ui/component-name
  2. Missing Environment Variables: Check that your env.example file follows the format:

    VARIABLE_NAME=example_value
    
  3. Missing Routes: Ensure your routes file is named correctly (routes.ts, routes.tsx, routes.js, or routes.jsx) and is in the addon's root directory.

  4. Missing Packages: The script only detects non-relative imports. If a package is missing, check that it's imported using the standard import syntax.

Manually Editing the Configuration

After the script generates the addon.jsonc file, you can manually edit it to add or modify any configuration options that weren't automatically detected.


README for how the Install Add On works

This document explains the installAddon.mjs script, which automates the installation of RedwoodSDK addons into your project.

Overview

The installAddon.mjs script is a comprehensive tool that handles all aspects of installing an addon into your RedwoodSDK project, including:

  • Copying addon files to the correct location
  • Installing required dependencies
  • Setting up environment variables
  • Injecting CSS styles
  • Adding routes to your application
  • Setting up Prisma schema
  • Installing ShadCN UI components

Usage

node src/scripts/installAddon.mjs install <addonName> [options]

Options

Option Description
--repo <url> Install from a GitHub repository
--source <path> Full path to the addon directory (not its parent)
--dest <path> Destination directory (defaults to src/app/addons)
--help Display help message

Examples

Install from a local directory:

node src/scripts/installAddon.mjs install suggest --source /path/to/addons/suggest

Install from a GitHub repository:

node src/scripts/installAddon.mjs install suggest --repo https://github.com/username/repo/addons

Installation Process

The script performs the following steps during installation:

1. Parse the addon.jsonc File

The script reads the addon's configuration from its addon.jsonc file, which contains information about:

  • Addon name and description
  • Required packages
  • Environment variables
  • Routes configuration
  • ShadCN UI components
  • CSS styles
  • Post-install message

2. Install Framework Dependencies

If the addon requires specific frameworks, the script will install them:

  • Tailwind CSS: If tailwind: true is specified in the addon.jsonc
  • ShadCN UI: If shadcn: true or shadcn: { required: true } is specified

3. Install ShadCN Components

If the addon uses ShadCN UI components, the script will:

  1. Ensure ShadCN UI is installed in your project
  2. Install each required component listed in the shadcn.components array

4. Install Package Dependencies

The script installs any packages listed in the packages array using pnpm add.

5. Set Up Environment Variables

For each environment variable listed in the env array, the script:

  1. Checks if the variable already exists in your .env file
  2. If not, adds the variable to your .env file (without a value)

6. Inject CSS Styles

If the addon includes CSS styles:

  1. The script looks for the target styles file specified in styles.injectInto
  2. Adds the import directive specified in styles.injectDirective
  3. Ensures proper ordering with Tailwind and ShadCN imports if needed

7. Add Routes

If the addon includes routes:

  1. Adds an import statement for the routes file to your worker.tsx
  2. Adds the routes to your application's render array
  3. Applies any specified route prefix

8. Set Up Prisma Schema

The script:

  1. Ensures the proper Prisma directory structure exists
  2. Merges any Prisma schema files from the addon
  3. Creates a migration for the merged schema

9. Generate Routes

Finally, the script runs the route generation process to update your application's routing.

Addon Source Options

Local Installation

When using the --source flag, you specify the exact directory containing the addon files. The script will:

  1. Copy all files from the source directory to your project's addons directory
  2. Process the addon.jsonc file to complete the installation

GitHub Installation

When using the --repo flag, you specify a GitHub repository URL. The script will:

  1. Use degit to clone the repository into your project's addons directory
  2. Process the addon.jsonc file to complete the installation

Troubleshooting

If you encounter issues during installation:

  1. Missing addon.jsonc: Ensure the addon directory contains a valid addon.jsonc file
  2. Failed package installation: Check that the required packages are available in npm
  3. ShadCN component errors: Verify that the components listed in the addon.jsonc exist in the ShadCN UI library
  4. Route conflicts: Check for route path conflicts with existing routes in your application

Advanced Usage

Custom Destination Directory

By default, addons are installed to src/app/addons, but you can specify a custom destination with the --dest flag:

node src/scripts/installAddon.mjs install suggest --source /path/to/suggest --dest /custom/path

Manual Configuration

After installation, you can manually edit the addon files in your project's addons directory to customize its behavior.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions