Repository: Wulf/create-rust-app (language: rust)

Issue:
Improve CI pipeline
We could improve the CI pipeline by testing different combinations of features instead of just using the default features
out-of-date readme and help messages
readme and help messages still refer to the Dev plugin (which is now enabled by default)

this may not be intended


Discussion / hints:
the only question here is which combinations to test
yeah we should make a note in the readme about this

Also something about falling back to `cargo backend` and `cargo frontend` if you prefer having your compiler messages in the terminal (and basically not using plugin_dev)

Fix patch:
diff --git a/.github/workflows/CLI-ActixPostgres-CI.yml b/.github/workflows/CLI-ActixPostgres-CI.yml
new file mode 100644
index 00000000..8f692063
--- /dev/null
+++ b/.github/workflows/CLI-ActixPostgres-CI.yml
@@ -0,0 +1,225 @@
+name: CLI Continuous Integration (Compilation tests for variations of Actix + Postgres)
+on:
+  workflow_dispatch:
+  push:
+    branches: 
+      - "main"
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+  pull_request:
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+env:
+  CARGO_TERM_COLOR: always
+  
+concurrency:
+  group:  CI-AP-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  # naming convention is: [backend]-[database]-[plugins]
+  Actix-Postgres-None:
+    name: Actix w/ Postgres and no plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run 
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-All:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and all valid plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=auth,container,graphql,storage,utoipa test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-Container:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and the container plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=container test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-Auth:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and the auth plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-Storage:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and the storage plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-GraphQL:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and the graphql plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=graphql,auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Postgres-Utoipa:
+    needs: [Actix-Postgres-None]
+    name: Actix w/ Postgres and the utoipa plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b actix-web --plugins=auth,utoipa test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
\ No newline at end of file
diff --git a/.github/workflows/CLI-ActixSqlite-CI.yml b/.github/workflows/CLI-ActixSqlite-CI.yml
new file mode 100644
index 00000000..b292bff5
--- /dev/null
+++ b/.github/workflows/CLI-ActixSqlite-CI.yml
@@ -0,0 +1,225 @@
+name: CLI Continuous Integration (Compilation tests for variations of Actix + Sqlite)
+on:
+  workflow_dispatch:
+  push:
+    branches: 
+      - "main"
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+  pull_request:
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+env:
+  CARGO_TERM_COLOR: always
+  
+concurrency:
+  group:  CI-AS-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  # naming convention is: [backend]-[database]-[plugins]
+  Actix-Sqlite-None:
+    name: Actix w/ Sqlite and no plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Sqlite-All:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and all valid plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=auth,container,graphql,storage,utoipa test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+  
+  Actix-Sqlite-Container:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and the container plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=container test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Sqlite-Auth:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and the auth plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Sqlite-Storage:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and the storage plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Sqlite-GraphQL:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and the graphql plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=graphql,auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Actix-Sqlite-Utoipa:
+    needs: [Actix-Sqlite-None]
+    name: Actix w/ Sqlite and the utoipa plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-AS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b actix-web --plugins=auth,utoipa test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
\ No newline at end of file
diff --git a/.github/workflows/CLI-PoemPostgres-CI.yml b/.github/workflows/CLI-PoemPostgres-CI.yml
new file mode 100644
index 00000000..5b4713d7
--- /dev/null
+++ b/.github/workflows/CLI-PoemPostgres-CI.yml
@@ -0,0 +1,196 @@
+name: CLI Continuous Integration (Compilation tests for variations of Poem + Postgres)
+on:
+  workflow_dispatch:
+  push:
+    branches: 
+      - "main"
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+  pull_request:
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+env:
+  CARGO_TERM_COLOR: always
+  
+concurrency:
+  group:  CI-PP-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  # naming convention is: [backend]-[database]-[plugins]
+  Poem-Postgres-None:
+    name: Poem w/ Postgres and no plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+  
+  Poem-Postgres-All:
+    needs: [Poem-Postgres-None]
+    name: Poem w/ Postgres and all valid plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem --plugins=auth,container,graphql,storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Postgres-Container:
+    needs: [Poem-Postgres-None]
+    name: Poem w/ Postgres and the container plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem --plugins=container test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Postgres-Auth:
+    needs: [Poem-Postgres-None]
+    name: Poem w/ Postgres and the auth plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem --plugins=auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Postgres-Storage:
+    needs: [Poem-Postgres-None]
+    name: Poem w/ Postgres and the storage plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem --plugins=storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Postgres-GraphQL:
+    needs: [Poem-Postgres-None]
+    name: Poem w/ Postgres and the graphql plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PP-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d postgres -b poem --plugins=graphql,auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
diff --git a/.github/workflows/CLI-PoemSqlite-CI.yml b/.github/workflows/CLI-PoemSqlite-CI.yml
new file mode 100644
index 00000000..5a1d223a
--- /dev/null
+++ b/.github/workflows/CLI-PoemSqlite-CI.yml
@@ -0,0 +1,197 @@
+name: CLI Continuous Integration (Compilation tests for variations of Poem + Sqlite)
+on:
+  workflow_dispatch:
+  push:
+    branches: 
+      - "main"
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+  pull_request:
+    paths: 
+      - "**.rs"
+      - "Cargo.lock"
+      - "Cargo.toml"
+env:
+  CARGO_TERM_COLOR: always
+  
+concurrency:
+  group:  CI-PS-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  # naming convention is: [backend]-[database]-[plugins]
+  Poem-Sqlite-None:
+    name: Poem w/ Sqlite and no plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+ 
+  Poem-Sqlite-All:
+    needs: [Poem-Sqlite-None]
+    name: Poem w/ Sqlite and all valid plugins
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem --plugins=auth,container,graphql,storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Sqlite-Container:
+    needs: [Poem-Sqlite-None]
+    name: Poem w/ Sqlite and the container plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem --plugins=container test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Sqlite-Auth:
+    needs: [Poem-Sqlite-None]
+    name: Poem w/ Sqlite and the auth plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem --plugins=auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Sqlite-Storage:
+    needs: [Poem-Sqlite-None]
+    name: Poem w/ Sqlite and the storage plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem --plugins=storage test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
+
+  Poem-Sqlite-GraphQL:
+    needs: [Poem-Sqlite-None]
+    name: Poem w/ Sqlite and the graphql plugin
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3.3.0
+      - uses: rui314/setup-mold@v1
+      - uses: actions-rs/toolchain@v1.0.7
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - uses: actions/cache@v3.2.5
+        with:
+          path: |
+            **/.cargo/.build
+            **/target
+          key: ${{ runner.os }}-cargo-cli-PS-${{ hashFiles('**/Cargo.lock') }}
+      - run: git config --global user.name test
+      - run: git config --global user.email example@email.com
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: run
+          args: --bin create-rust-app -- create -c -d sqlite -b poem --plugins=graphql,auth test-project
+      - uses: actions-rs/cargo@v1.0.3
+        with:
+          command: build
+          args: --manifest-path=test-project/Cargo.toml
diff --git a/Cargo.toml b/Cargo.toml
index 914c3362..71597205 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,6 @@
 members = [
   "create-rust-app",
   "create-rust-app_cli",
-  "create-rust-app_cli/qsync"
+  "create-rust-app_cli/qsync",
 ]
-exclude = ["docs", "tests"]
+exclude = ["docs", "tests", "test-project"]
diff --git a/create-rust-app/src/dev/backend_compiling_server.rs b/create-rust-app/src/dev/backend_compiling_server.rs
index 08901520..4214423b 100644
--- a/create-rust-app/src/dev/backend_compiling_server.rs
+++ b/create-rust-app/src/dev/backend_compiling_server.rs
@@ -113,13 +113,12 @@ pub async fn start(
         let ws_s = dev_server_events_s.clone();
         let migrations_dir = migrations_dir.clone();
         async move {
-            let exit_events = action
+            // no exit events
+            if !action
                 .events
                 .iter()
-                .filter(|e| e.metadata.contains_key("exit-watchexec"))
-                .collect::<Vec<_>>();
-
-            if !exit_events.is_empty() {
+                .any(|e| e.metadata.contains_key("exit-watchexec"))
+            {
                 println!("continuous backend compilation stopped.");
                 let mut m = state3.lock().await;
                 m.watchexec_running = false;
@@ -135,30 +134,26 @@ pub async fn start(
             // println!("=> ignoring {:#?}", files_to_ignore);
 
             let mut touched_migrations_dir = false;
-            let file_events = action
-                .events
-                .iter()
-                .filter(|e| {
-                    e.tags.iter().any(|t| match t {
-                        Tag::Path { path, file_type: _ } => {
-                            if path
-                                .to_str()
-                                .unwrap()
-                                .starts_with(migrations_dir.as_os_str().to_str().unwrap())
-                            {
-                                touched_migrations_dir = true;
-                            }
 
-                            !files_to_ignore.iter().any(|file_to_ignore| {
-                                path.to_str().unwrap().ends_with(file_to_ignore)
-                            })
+            // no file events
+            if !action.events.iter().any(|e| {
+                e.tags.iter().any(|t| match t {
+                    Tag::Path { path, file_type: _ } => {
+                        if path
+                            .to_str()
+                            .unwrap()
+                            .starts_with(migrations_dir.as_os_str().to_str().unwrap())
+                        {
+                            touched_migrations_dir = true;
                         }
-                        _ => false,
-                    })
-                })
-                .collect::<Vec<_>>();
 
-            if !file_events.is_empty() {
+                        !files_to_ignore
+                            .iter()
+                            .any(|file_to_ignore| path.to_str().unwrap().ends_with(file_to_ignore))
+                    }
+                    _ => false,
+                })
+            }) {
                 // compile
                 ws_s.send(DevServerEvent::BackendCompiling(true)).ok();
                 if compile(project_dir, ws_s.clone()) {
@@ -249,7 +244,7 @@ fn compile(project_dir: &'static str, ws_s: Sender<DevServerEvent>) -> bool {
                     .duration_since(start_time)
                     .map(|d| d.as_secs_f32())
                     .map(|d| format!("{d:.2}"))
-                    .unwrap_or("?".to_string());
+                    .unwrap_or_else(|_| "?".to_string());
 
                 if finished.success {
                     println!("✅ Compiled ({compile_time_s} seconds)");
diff --git a/create-rust-app_cli/qsync/src/hook.rs b/create-rust-app_cli/qsync/src/hook.rs
index 7d2f73cd..7a38ebf9 100644
--- a/create-rust-app_cli/qsync/src/hook.rs
+++ b/create-rust-app_cli/qsync/src/hook.rs
@@ -1,5 +1,4 @@
 use std::fmt::Write as _;
-use crate::utils;
 
 use super::params::is_primitive_type;
 use super::processor::HttpVerb;
@@ -203,7 +202,7 @@ impl Hook {
             }
         }
 
-        if (/* !self.path_params.is_empty() || */ !self.query_params.is_empty())
+        if (/* !self.path_params.is_empty() || */!self.query_params.is_empty())
             && !self.body_params.is_empty()
         {
             query_key.push_str(", ");
@@ -223,17 +222,23 @@ impl Hook {
             query_key.insert_str(0, ", ")
         }
 
-        let query_key_base = self.endpoint_url.trim_start_matches("/api/").split("/").into_iter().map(|t| {
-            // in actix-web, paths which have {} denote a path param
-            if t.starts_with("{") && t.ends_with("}") {
-                let path_param = t.chars().skip(1).take(t.len() - 2).collect::<String>();
-                format!("pathParams.{path_param}")
-            } else {
-                format!("\"{t}\"").to_string()
-            }
-        }).collect::<Vec<_>>();
+        let query_key_base = self
+            .endpoint_url
+            .trim_start_matches("/api/")
+            .split('/')
+            .into_iter()
+            .map(|t| {
+                // in actix-web, paths which have {} denote a path param
+                if t.starts_with('{') && t.ends_with('}') {
+                    let path_param = t.chars().skip(1).take(t.len() - 2).collect::<String>();
+                    format!("pathParams.{path_param}")
+                } else {
+                    format!("\"{t}\"")
+                }
+            })
+            .collect::<Vec<_>>();
 
-        query_key.insert_str(0, &format!("{}", query_key_base.join(", ")));
+        query_key.insert_str(0, &query_key_base.join(", "));
 
         query_key
     }
diff --git a/create-rust-app_cli/qsync/src/lib.rs b/create-rust-app_cli/qsync/src/lib.rs
index 2905e537..d1fc19e8 100644
--- a/create-rust-app_cli/qsync/src/lib.rs
+++ b/create-rust-app_cli/qsync/src/lib.rs
@@ -1,10 +1,10 @@
 extern crate syn;
 
-mod utils;
 mod hook;
 mod params;
 mod processor;
+mod utils;
 pub use processor::process;
 
 /// the #[qsync] attribute macro which marks structs and types to be translated into queries
-pub use qsync_macro::qsync;
\ No newline at end of file
+pub use qsync_macro::qsync;
diff --git a/create-rust-app_cli/qsync/src/processor.rs b/create-rust-app_cli/qsync/src/processor.rs
index 29bc12f5..63d25a62 100644
--- a/create-rust-app_cli/qsync/src/processor.rs
+++ b/create-rust-app_cli/qsync/src/processor.rs
@@ -1,13 +1,14 @@
 use super::hook::{Hook, HookBodyParam, HookPathParam, HookQueryParam};
 use super::params::generic_to_typsecript_type;
+use darling::FromMeta;
 use regex::Regex;
 use std::fs::File;
 use std::io::Read;
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
-use darling::FromMeta;
 
+use crate::utils::file_path_to_vec_string;
 use syn::FnArg;
 use syn::Pat;
 use syn::PatType;
@@ -15,7 +16,6 @@ use syn::PathArguments;
 use syn::Type;
 use syn::TypePath;
 use walkdir::WalkDir;
-use crate::utils::file_path_to_vec_string;
 
 extern crate inflector;
 use super::processor::inflector::Inflector;
@@ -46,7 +46,10 @@ fn has_qsync_attribute(
         let meta = attr.parse_meta().unwrap();
 
         // extract and compare against attribute's identifier (#[path::to::identifier])
-        let attr_identifier = meta.path().segments.last()
+        let attr_identifier = meta
+            .path()
+            .segments
+            .last()
             .map(|r| r.ident.to_string())
             .unwrap_or_default();
 
@@ -64,7 +67,9 @@ fn has_qsync_attribute(
                 let args = args.unwrap();
 
                 qsync_props.is_mutation = args.mutate.unwrap_or_default();
-                if args.return_type.is_some() { qsync_props.return_type = args.return_type.unwrap(); }
+                if args.return_type.is_some() {
+                    qsync_props.return_type = args.return_type.unwrap();
+                }
             }
             "get" => {
                 has_actix_attribute = true;
@@ -562,11 +567,11 @@ pub fn process(input_paths: Vec<PathBuf>, output_path: PathBuf, is_debug: bool)
         //         added, existing, &output_path
         //     )
         // } else {
-            let mut file: File = File::create(&output_path).expect("Unable to write to file");
-            match file.write_all(state.types.as_bytes()) {
-                Ok(_) => println!("Successfully generated hooks, see {output_path:#?}"),
-                Err(_) => println!("Failed to generate types, an error occurred."),
-            }
+        let mut file: File = File::create(&output_path).expect("Unable to write to file");
+        match file.write_all(state.types.as_bytes()) {
+            Ok(_) => println!("Successfully generated hooks, see {output_path:#?}"),
+            Err(_) => println!("Failed to generate types, an error occurred."),
+        }
         // }
     }
 
diff --git a/create-rust-app_cli/src/content/project.rs b/create-rust-app_cli/src/content/project.rs
index 7459efe1..57ee6d6e 100644
--- a/create-rust-app_cli/src/content/project.rs
+++ b/create-rust-app_cli/src/content/project.rs
@@ -122,6 +122,7 @@ pub struct CreationOptions {
     pub cra_enabled_features: Vec<String>,
     pub backend_framework: BackendFramework,
     pub backend_database: BackendDatabase,
+    pub cli_mode: bool,
 }
 
 pub fn remove_non_framework_files(
@@ -229,10 +230,11 @@ pub fn create(project_name: &str, creation_options: CreationOptions) -> Result<(
             Err(err) => logger::exit("std::fs::canonicalize():", err),
         };
 
-        let proceed = Confirm::with_theme(&ColorfulTheme::default())
-            .with_prompt("Delete directory contents?")
-            .default(false)
-            .interact()?;
+        let proceed = !creation_options.cli_mode
+            && Confirm::with_theme(&ColorfulTheme::default())
+                .with_prompt("Delete directory contents?")
+                .default(false)
+                .interact()?;
 
         if proceed {
             match std::fs::remove_dir_all(&project_dir) {
@@ -258,6 +260,79 @@ pub fn create(project_name: &str, creation_options: CreationOptions) -> Result<(
         style(&format!("{:?}", creation_options.backend_framework)).yellow()
     ));
 
+    // check if a git user name & email are configured, if not either ask for one or fail if in cli-mode
+    logger::command_msg("git config user.name");
+    let git_config_user_name = git::check_config(&project_dir, "user.name");
+    if !git_config_user_name {
+        logger::message("You do not have a git user name set.");
+
+        // if being created in cli-only mode, don't ask for a new user.name,
+        // just tell them how to set it and exit with status code 1
+        if creation_options.cli_mode {
+            logger::error("Running in non-interactive mode and git user.name not set.\nYou can set it with this command:\n\t`git config --global user.name <name>`");
+            std::process::exit(1);
+        }
+
+        let mut valid_user_name = false;
+        let mut invalid_input = false;
+
+        while !valid_user_name {
+            let prompt_message = if invalid_input {
+                "(try again) Choose a name to use when committing:"
+            } else {
+                "Choose a name to use when committing:"
+            };
+            let input: String = Input::new().with_prompt(prompt_message).interact()?;
+
+            logger::command_msg(&format!("git config user.name {:#?}", &input));
+
+            if !input.is_empty()
+                && git::set_config(&project_dir, "user.name", &input)
+                && git::check_config(&project_dir, "user.name")
+            {
+                valid_user_name = true;
+            } else {
+                invalid_input = true;
+            }
+        }
+    }
+
+    logger::command_msg("git config user.email");
+    let git_config_user_email = git::check_config(&project_dir, "user.email");
+    if !git_config_user_email {
+        logger::message("You do not have a git user email set.");
+
+        // if being created in cli-only mode, don't ask for a new user.email,
+        // just tell them how to set it and exit with status code 1
+        if creation_options.cli_mode {
+            logger::error("Running in non-interactive mode and git user.email not set.\nYou can set it with this command:\n\t`git config --global user.email <email>`");
+            std::process::exit(1);
+        }
+
+        let mut valid_user_email = false;
+        let mut invalid_input = false;
+
+        while !valid_user_email {
+            let prompt_message = if invalid_input {
+                "(try again) Choose an email to use when committing:"
+            } else {
+                "Choose an email to use when committing:"
+            };
+            let input: String = Input::new().with_prompt(prompt_message).interact()?;
+
+            logger::command_msg(&format!("git config user.email {:#?}", &input));
+
+            if !input.is_empty()
+                && git::set_config(&project_dir, "user.email", &input)
+                && git::check_config(&project_dir, "user.email")
+            {
+                valid_user_email = true;
+            } else {
+                invalid_input = true;
+            }
+        }
+    }
+
     match std::fs::create_dir_all(&project_dir) {
         Ok(_) => {}
         Err(err) => logger::exit("std::fs::create_dir_all():", err),
@@ -483,66 +558,6 @@ pub fn create(project_name: &str, creation_options: CreationOptions) -> Result<(
         std::process::exit(1);
     }
 
-    logger::command_msg("git config user.name");
-
-    let git_config_user_name = git::check_config(&project_dir, "user.name");
-
-    if !git_config_user_name {
-        logger::message("You do not have a git user name set.");
-
-        let mut valid_user_name = false;
-        let mut invalid_input = false;
-
-        while !valid_user_name {
-            let prompt_message = if invalid_input {
-                "(try again) Choose a name to use when committing:"
-            } else {
-                "Choose a name to use when committing:"
-            };
-            let input: String = Input::new().with_prompt(prompt_message).interact()?;
-
-            logger::command_msg(&format!("git config user.name {:#?}", &input));
-
-            if !input.is_empty()
-                && git::set_config(&project_dir, "user.name", &input)
-                && git::check_config(&project_dir, "user.name")
-            {
-                valid_user_name = true;
-            } else {
-                invalid_input = true;
-            }
-        }
-    }
-
-    let git_config_user_email = git::check_config(&project_dir, "user.email");
-
-    if !git_config_user_email {
-        logger::message("You do not have a git user email set.");
-
-        let mut valid_user_email = false;
-        let mut invalid_input = false;
-
-        while !valid_user_email {
-            let prompt_message = if invalid_input {
-                "(try again) Choose an email to use when committing:"
-            } else {
-                "Choose an email to use when committing:"
-            };
-            let input: String = Input::new().with_prompt(prompt_message).interact()?;
-
-            logger::command_msg(&format!("git config user.email {:#?}", &input));
-
-            if !input.is_empty()
-                && git::set_config(&project_dir, "user.email", &input)
-                && git::check_config(&project_dir, "user.email")
-            {
-                valid_user_email = true;
-            } else {
-                invalid_input = true;
-            }
-        }
-    }
-
     logger::command_msg("git add -A");
 
     let git_add = std::process::Command::new("git")
diff --git a/create-rust-app_cli/src/main.rs b/create-rust-app_cli/src/main.rs
index 5f6e724d..0fc1fbb6 100644
--- a/create-rust-app_cli/src/main.rs
+++ b/create-rust-app_cli/src/main.rs
@@ -14,8 +14,8 @@ use std::path::PathBuf;
 use crate::project::CreationOptions;
 use content::project;
 use dialoguer::{console::Term, theme::ColorfulTheme, Input, MultiSelect, Select};
+
 use utils::{fs, logger};
-use qsync;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
 pub enum BackendFramework {
@@ -59,10 +59,9 @@ enum Commands {
             short = 'c',
             long = "cli",
             name = "non-interactive mode",
-            help = "Configure project through interactive CLI arguments.",
+            help = "Configure project through CLI arguments, not the interactive TUI.",
             requires = "database",
-            requires = "backend framework",
-            requires = "plugins"
+            requires = "backend framework"
         )]
         cli_mode: bool,
 
@@ -77,7 +76,6 @@ enum Commands {
             long="database",
             name="database",
             help="Database to use",
-            require_equals=true,
             value_name="DATABASE",
             value_parser=EnumValueParser::<BackendDatabase>::new(),
             ignore_case=true,
@@ -89,7 +87,6 @@ enum Commands {
             long="backend",
             name="backend framework",
             help="Rust backend framework to use",
-            require_equals=true,
             value_name="FRAMEWORK",
             value_parser=EnumValueParser::<BackendFramework>::new(),
             ignore_case=true,
@@ -103,12 +100,10 @@ enum Commands {
             help="Plugins for your new project\nComma separated list ",
             num_args=1..,
             value_delimiter=',',
-            require_equals=true,
             value_name="PLUGINS",
             value_parser=[
                 PossibleValue::new("auth").help("Authentication Plugin: local email-based authentication"),
                 PossibleValue::new("container").help("Container Plugin: dockerize your app"),
-                PossibleValue::new("dev").help("Development Plugin: adds dev warnings and an admin portal"),
                 PossibleValue::new("storage").help("Storage Plugin: adds S3 file storage capabilities"),
                 PossibleValue::new("graphql").help("GraphQL Plugin: bootstraps a GraphQL setup including a playground"),
                 PossibleValue::new("utoipa").help("Utoipa Plugin: Autogenerated OpenAPI documentation served in a SwaggerUI playground"),
@@ -291,7 +286,6 @@ fn create_project(
             .map(|plugin| match plugin.as_str() {
                 "auth" => "plugin_auth".to_string(),
                 "container" => "plugin_container".to_string(),
-                "dev" => "plugin_dev".to_string(),
                 "storage" => "plugin_storage".to_string(),
                 "graphql" => "plugin_graphql".to_string(),
                 "utoipa" => "plugin_utoipa".to_string(),
@@ -299,57 +293,57 @@ fn create_project(
             })
             .collect(),
         None => {
-            if cli_mode {
-                panic!("Fatal: No plugins specified")
-            }
-            logger::message("Please select plugins for your new project:");
-            logger::message(
-                "Use UP/DOWN arrows to navigate, SPACE to enable/disable a plugin, and ENTER to confirm.",
-            );
-
-            let items = vec![
-                "Authentication Plugin: local email-based authentication",
-                "Container Plugin: dockerize your app",
-                // "Development Plugin: adds dev warnings and an admin portal",
-                "Storage Plugin: adds S3 file storage capabilities",
-                "GraphQL Plugin: bootstraps a GraphQL setup including a playground",
-                "Utoipa Plugin: Autogenerated OpenAPI documentation served in a SwaggerUI playground",
-            ];
-            let chosen: Vec<usize> = MultiSelect::with_theme(&ColorfulTheme::default())
-                .items(&items)
-                .defaults(&[true, true, true, true, false])
-                .interact()?;
-
-            let add_plugin_auth = chosen.iter().any(|x| *x == 0);
-            let add_plugin_container = chosen.iter().any(|x| *x == 1);
-            let add_plugin_dev = true; // chosen.iter().any(|x| *x == 2);
-            let add_plugin_storage = chosen.iter().any(|x| *x == 3);
-            let add_plugin_graphql = chosen.iter().any(|x| *x == 4);
-            let add_plugin_utoipa = chosen.iter().any(|x| *x == 5);
-
-            let mut features: Vec<String> = vec![];
-            if add_plugin_auth {
-                features.push("plugin_auth".to_string());
-            }
-            if add_plugin_container {
-                features.push("plugin_container".to_string());
-            }
-            if add_plugin_dev {
-                features.push("plugin_dev".to_string());
-            }
-            if add_plugin_storage {
-                features.push("plugin_storage".to_string());
-            }
-            if add_plugin_graphql {
-                features.push("plugin_graphql".to_string());
-            }
-            if add_plugin_utoipa {
-                features.push("plugin_utoipa".to_string());
-            }
+            if !cli_mode {
+                logger::message("Please select plugins for your new project:");
+                logger::message(
+                    "Use UP/DOWN arrows to navigate, SPACE to enable/disable a plugin, and ENTER to confirm.",
+                );
 
-            features
+                let items = vec![
+                    "Authentication Plugin: local email-based authentication",
+                    "Container Plugin: dockerize your app",
+                    // "Development Plugin: adds dev warnings and an admin portal",
+                    "Storage Plugin: adds S3 file storage capabilities",
+                    "GraphQL Plugin: bootstraps a GraphQL setup including a playground",
+                    "Utoipa Plugin: Autogenerated OpenAPI documentation served in a SwaggerUI playground",
+                ];
+                let chosen: Vec<usize> = MultiSelect::with_theme(&ColorfulTheme::default())
+                    .items(&items)
+                    .defaults(&[true, true, true, true, false])
+                    .interact()?;
+
+                let add_plugin_auth = chosen.iter().any(|x| *x == 0);
+                let add_plugin_container = chosen.iter().any(|x| *x == 1);
+                let add_plugin_storage = chosen.iter().any(|x| *x == 3);
+                let add_plugin_graphql = chosen.iter().any(|x| *x == 4);
+                let add_plugin_utoipa = chosen.iter().any(|x| *x == 5);
+
+                let mut features: Vec<String> = vec![];
+                if add_plugin_auth {
+                    features.push("plugin_auth".to_string());
+                }
+                if add_plugin_container {
+                    features.push("plugin_container".to_string());
+                }
+                if add_plugin_storage {
+                    features.push("plugin_storage".to_string());
+                }
+                if add_plugin_graphql {
+                    features.push("plugin_graphql".to_string());
+                }
+                if add_plugin_utoipa {
+                    features.push("plugin_utoipa".to_string());
+                }
+
+                features
+            } else {
+                vec![]
+            }
         }
     };
+    //add the dev plugin
+    cra_enabled_features.push("plugin_dev".to_string());
+
     // add database and framework to enabled features
     cra_enabled_features.push(match backend_database {
         BackendDatabase::Postgres => "database_postgres".to_string(),
@@ -366,6 +360,7 @@ fn create_project(
             cra_enabled_features: cra_enabled_features.clone(),
             backend_framework,
             backend_database,
+            cli_mode,
         },
     )?;
 


Test patch: