PhoenixKit - The Elixir Phoenix Starter Kit for SaaS apps

We are actively building PhoenixKit, a comprehensive SaaS starter kit for the Elixir/Phoenix ecosystem. Our goal is to eliminate the need to reinvent the wheel every time we all start a new SaaS project.

🚧 Early Access - We Need Your Feedback! PhoenixKit is under heavy development and we're looking for early adopters to test, provide feedback, and help shape the future of this toolkit. If you're building with Phoenix and want to skip the boilerplate setup, we'd love to have you try it out and share your experience.

With PhoenixKit, you will be able to create production-ready Elixir/Phoenix apps much faster and focus on your unique business logic instead of reimplementing common SaaS patterns.

πŸ“¦ Current PhoenixKit Features / Modules:

πŸ›£οΈ Roadmap / Ideas / Feature requests

πŸ’‘ Send your ideas and suggestions about any existing modules and features our way. Start building your apps today!

Installation

PhoenixKit provides multiple installation methods to suit different project needs and developer preferences.

Semi-Automatic Installation

Recommended for most projects

Add both phoenix_kit and igniter to your project dependencies:

# mix.exs
def deps do
[
{:phoenix_kit, "~> 1.2"},
{:igniter, "~> 0.6.0", only: [:dev]}
]
end

Then run the PhoenixKit installer:

mix deps.get
mix phoenix_kit.install

This will automatically:

Optional parameters:

# Specify custom repository
mix phoenix_kit.install --repo MyApp.Repo
# Use PostgreSQL schema prefix for table isolation
mix phoenix_kit.install --prefix "auth" --create-schema
# Specify custom router file path
mix phoenix_kit.install --router-path lib/my_app_web/router.ex

Manual Installation

  1. Add {:phoenix_kit, "~> 1.2"} to mix.exs
  2. Run mix deps.get && mix phoenix_kit.gen.migration
  3. Configure repository: config :phoenix_kit, repo: MyApp.Repo
  4. Add phoenix_kit_routes() to your router
  5. Run mix ecto.migrate

Quick Start

Visit these URLs after installation:

Configuration

Basic Setup

# config/config.exs (automatically added by installer)
config :phoenix_kit, repo: YourApp.Repo
# Production mailer
config :phoenix_kit, PhoenixKit.Mailer,
adapter: Swoosh.Adapters.SMTP,
relay: "smtp.your-provider.com",
username: System.get_env("SMTP_USERNAME"),
password: System.get_env("SMTP_PASSWORD"),
port: 587

Layout Integration

# Use your app's layout (optional)
config :phoenix_kit,
layout: {YourAppWeb.Layouts, :app},
root_layout: {YourAppWeb.Layouts, :root}

Note: Run mix deps.compile phoenix_kit --force after changing configuration.

Advanced Options

Routes

Public Routes

Authenticated Routes

Admin Routes (Owner/Admin only)

API Usage

Current User Access

# In your controller or LiveView
user = conn.assigns[:phoenix_kit_current_user]
# Or using Scope system
scope = socket.assigns[:phoenix_kit_current_scope]
PhoenixKit.Users.Auth.Scope.authenticated?(scope)

Role-Based Access

# Check user roles
PhoenixKit.Users.Roles.user_has_role?(user, "Admin")
# Promote user to admin
{:ok, _} = PhoenixKit.Users.Roles.promote_to_admin(user)
# Use in LiveView sessions
on_mount: [{PhoenixKitWeb.Users.Auth, :phoenix_kit_ensure_admin}]

Authentication Helpers

# In your LiveView sessions
on_mount: [{PhoenixKitWeb.Users.Auth, :phoenix_kit_mount_current_scope}]
on_mount: [{PhoenixKitWeb.Users.Auth, :phoenix_kit_ensure_authenticated_scope}]

Database Schema

PhoenixKit creates these PostgreSQL tables:

Role-Based Access Control

System Roles

Role Management

# Check roles
PhoenixKit.Users.Roles.get_user_roles(user)
# => ["Admin", "User"]
# Role promotion/demotion
PhoenixKit.Users.Roles.promote_to_admin(user)
PhoenixKit.Users.Roles.demote_to_user(user)
# Create custom roles
PhoenixKit.Users.Roles.create_role(%{name: "Manager", description: "Team lead"})

Built-in Admin Interface

Architecture

PhoenixKit follows professional library patterns:

Contributing

  1. Fork and create feature branch
  2. Add tests: mix test
  3. Run quality checks: mix quality
  4. Submit pull request

License

MIT License - see CHANGELOG.md for version history.


Built with ❀️ for the Elixir Phoenix community