diff --git a/index.ts b/index.ts
index 36997386..2fcb2ce1 100755
--- a/index.ts
+++ b/index.ts
@@ -228,6 +228,9 @@ async function init() {
             },
             {
               title: 'Playwright',
+              description: answers.needsVitest
+                ? undefined
+                : 'also supports unit testing with Playwright Component Testing',
               value: 'playwright'
             }
           ]
@@ -284,6 +287,7 @@ async function init() {
   const needsCypress = argv.cypress || argv.tests || needsE2eTesting === 'cypress'
   const needsCypressCT = needsCypress && !needsVitest
   const needsPlaywright = argv.playwright || needsE2eTesting === 'playwright'
+  const needsPlaywrightCT = needsPlaywright && !needsVitest
 
   const root = path.join(cwd, targetDir)
 
@@ -332,6 +336,9 @@ async function init() {
   if (needsPlaywright) {
     render('config/playwright')
   }
+  if (needsPlaywrightCT) {
+    render('config/playwright-ct')
+  }
   if (needsTypeScript) {
     render('config/typescript')
 
@@ -437,8 +444,9 @@ async function init() {
       needsTypeScript,
       needsVitest,
       needsCypress,
-      needsPlaywright,
       needsCypressCT,
+      needsPlaywright,
+      needsPlaywrightCT,
       needsEslint
     })
   )
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0f0dd40e..bff90c87 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -113,6 +113,15 @@ importers:
         specifier: ^1.33.0
         version: 1.33.0
 
+  template/config/playwright-ct:
+    devDependencies:
+      '@playwright/experimental-ct-vue':
+        specifier: ^1.33.0
+        version: 1.33.0(@types/node@18.16.8)(vite@4.3.5)(vue@3.3.2)
+      '@playwright/test':
+        specifier: ^1.33.0
+        version: 1.33.0
+
   template/config/router:
     dependencies:
       vue:
@@ -785,12 +794,46 @@ packages:
       fastq: 1.13.0
     dev: true
 
+  /@playwright/experimental-ct-core@1.33.0(@types/node@18.16.8):
+    resolution: {integrity: sha512-mfCpAdYDL5fR9PRZKXbgbeHBkWJZMRWmHofE4r9IP1D8tne/Sy1oZSnan7S8c1HGy6d9MAedpsn802uCzsYzCg==}
+    engines: {node: '>=14'}
+    hasBin: true
+    dependencies:
+      '@playwright/test': 1.33.0
+      vite: 4.3.5(@types/node@18.16.8)
+    transitivePeerDependencies:
+      - '@types/node'
+      - less
+      - sass
+      - stylus
+      - sugarss
+      - terser
+    dev: true
+
+  /@playwright/experimental-ct-vue@1.33.0(@types/node@18.16.8)(vite@4.3.5)(vue@3.3.2):
+    resolution: {integrity: sha512-vsYRD0MI3a7RLXhVOrAPqRJyaPajOn9lq3JFjZivNRrQylYhuNZW48vOhuzzlm40KZD3HCpUye2UzHhEAHuMxA==}
+    engines: {node: '>=14'}
+    hasBin: true
+    dependencies:
+      '@playwright/experimental-ct-core': 1.33.0(@types/node@18.16.8)
+      '@vitejs/plugin-vue': 4.2.3(vite@4.3.5)(vue@3.3.2)
+    transitivePeerDependencies:
+      - '@types/node'
+      - less
+      - sass
+      - stylus
+      - sugarss
+      - terser
+      - vite
+      - vue
+    dev: true
+
   /@playwright/test@1.33.0:
     resolution: {integrity: sha512-YunBa2mE7Hq4CfPkGzQRK916a4tuZoVx/EpLjeWlTVOnD4S2+fdaQZE0LJkbfhN5FTSKNLdcl7MoT5XB37bTkg==}
     engines: {node: '>=14'}
     hasBin: true
     dependencies:
-      '@types/node': 18.16.2
+      '@types/node': 18.16.8
       playwright-core: 1.33.0
     optionalDependencies:
       fsevents: 2.3.2
@@ -877,10 +920,6 @@ packages:
     resolution: {integrity: sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==}
     dev: true
 
-  /@types/node@18.16.2:
-    resolution: {integrity: sha512-GQW/JL/5Fz/0I8RpeBG9lKp0+aNcXEaVL71c0D2Q0QHDTFvlYKT7an0onCUXj85anv7b4/WesqdfchLc0jtsCg==}
-    dev: true
-
   /@types/node@18.16.8:
     resolution: {integrity: sha512-p0iAXcfWCOTCBbsExHIDFCfwsqFwBTgETJveKMT+Ci3LY9YqQCI91F5S+TB20+aRCXpcWfvx5Qr5EccnwCm2NA==}
     dev: true
diff --git a/template/config/playwright-ct/_gitignore b/template/config/playwright-ct/_gitignore
new file mode 100644
index 00000000..0fd20829
--- /dev/null
+++ b/template/config/playwright-ct/_gitignore
@@ -0,0 +1,3 @@
+test-results/
+playwright-report/
+/playwright/.cache/
diff --git a/template/config/playwright-ct/package.json b/template/config/playwright-ct/package.json
new file mode 100644
index 00000000..a786e152
--- /dev/null
+++ b/template/config/playwright-ct/package.json
@@ -0,0 +1,9 @@
+{
+  "scripts": {
+    "test:unit": "playwright test -c playwright-ct.config.ts"
+  },
+  "devDependencies": {
+    "@playwright/experimental-ct-vue": "^1.33.0",
+    "@playwright/test": "^1.33.0"
+  }
+}
diff --git a/template/config/playwright-ct/playwright-ct.config.ts b/template/config/playwright-ct/playwright-ct.config.ts
new file mode 100644
index 00000000..38928b4f
--- /dev/null
+++ b/template/config/playwright-ct/playwright-ct.config.ts
@@ -0,0 +1,54 @@
+import { defineConfig, devices } from '@playwright/experimental-ct-vue'
+import { resolve } from 'path'
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+  testDir: './',
+  /* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */
+  snapshotDir: './__snapshots__',
+  /* Maximum time one test can run for. */
+  timeout: 10 * 1000,
+  /* Run tests in files in parallel */
+  fullyParallel: true,
+  /* Fail the build on CI if you accidentally left test.only in the source code. */
+  forbidOnly: !!process.env.CI,
+  /* Retry on CI only */
+  retries: process.env.CI ? 2 : 0,
+  /* Opt out of parallel tests on CI. */
+  workers: process.env.CI ? 1 : undefined,
+  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+  reporter: 'html',
+  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+  use: {
+    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+    trace: 'on-first-retry',
+    /* Port to use for Playwright component endpoint. */
+    ctPort: 3100,
+    /* Vite configuration for Playwright component testing. */
+    ctViteConfig: {
+      resolve: {
+        alias: {
+          '@': resolve(__dirname, './src')
+        }
+      }
+    }
+  },
+
+  /* Configure projects for major browsers */
+  projects: [
+    {
+      name: 'chromium',
+      use: { ...devices['Desktop Chrome'] }
+    },
+    {
+      name: 'firefox',
+      use: { ...devices['Desktop Firefox'] }
+    },
+    {
+      name: 'webkit',
+      use: { ...devices['Desktop Safari'] }
+    }
+  ]
+})
diff --git a/template/config/playwright-ct/playwright.config.js b/template/config/playwright-ct/playwright.config.js
new file mode 100644
index 00000000..ffa2c33f
--- /dev/null
+++ b/template/config/playwright-ct/playwright.config.js
@@ -0,0 +1,54 @@
+const { defineConfig, devices } = require('@playwright/experimental-ct-vue')
+const { resolve } = require('path')
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+module.exports = defineConfig({
+  testDir: './',
+  /* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */
+  snapshotDir: './__snapshots__',
+  /* Maximum time one test can run for. */
+  timeout: 10 * 1000,
+  /* Run tests in files in parallel */
+  fullyParallel: true,
+  /* Fail the build on CI if you accidentally left test.only in the source code. */
+  forbidOnly: !!process.env.CI,
+  /* Retry on CI only */
+  retries: process.env.CI ? 2 : 0,
+  /* Opt out of parallel tests on CI. */
+  workers: process.env.CI ? 1 : undefined,
+  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+  reporter: 'html',
+  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+  use: {
+    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+    trace: 'on-first-retry',
+    /* Port to use for Playwright component endpoint. */
+    ctPort: 3100,
+    /* Vite configuration for Playwright component testing. */
+    ctViteConfig: {
+      resolve: {
+        alias: {
+          '@': resolve(__dirname, './src')
+        }
+      }
+    }
+  },
+
+  /* Configure projects for major browsers */
+  projects: [
+    {
+      name: 'chromium',
+      use: { ...devices['Desktop Chrome'] }
+    },
+    {
+      name: 'firefox',
+      use: { ...devices['Desktop Firefox'] }
+    },
+    {
+      name: 'webkit',
+      use: { ...devices['Desktop Safari'] }
+    }
+  ]
+})
diff --git a/template/config/playwright-ct/playwright/index.html b/template/config/playwright-ct/playwright/index.html
new file mode 100644
index 00000000..2468b1c8
--- /dev/null
+++ b/template/config/playwright-ct/playwright/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Testing Page</title>
+  </head>
+  <body>
+    <div id="root"></div>
+    <script type="module" src="./index.js"></script>
+  </body>
+</html>
diff --git a/template/config/playwright-ct/playwright/index.js b/template/config/playwright-ct/playwright/index.js
new file mode 100644
index 00000000..ac6de14b
--- /dev/null
+++ b/template/config/playwright-ct/playwright/index.js
@@ -0,0 +1,2 @@
+// Import styles, initialize component theme here.
+// import '../src/common.css';
diff --git a/template/config/playwright-ct/src/components/__tests__/HelloWorld.spec.ts b/template/config/playwright-ct/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 00000000..1807e915
--- /dev/null
+++ b/template/config/playwright-ct/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,16 @@
+import { expect, test } from '@playwright/experimental-ct-vue'
+import HelloWorld from '../HelloWorld.vue'
+
+
+test('playground', async ({ mount }) => {
+  await mount(HelloWorld, {
+    props: { msg: 'Hello Playwright' }
+  })
+})
+
+test('renders properly', async ({ mount }) => {
+  const component = await mount(HelloWorld, {
+    props: { msg: 'Hello Playwright' }
+  })
+  await expect(component.getByRole('heading', { level: 1 })).toContainText('Hello Playwright')
+})
diff --git a/utils/generateReadme.ts b/utils/generateReadme.ts
index 04fc3de0..400ef6f8 100644
--- a/utils/generateReadme.ts
+++ b/utils/generateReadme.ts
@@ -22,6 +22,7 @@ export default function generateReadme({
   needsCypress,
   needsCypressCT,
   needsPlaywright,
+  needsPlaywrightCT,
   needsVitest,
   needsEslint
 }) {
@@ -124,6 +125,26 @@ ${commandFor('test:e2e', '--debug')}
 `
   }
 
+  if (needsCypressCT) {
+    npmScriptsDescriptions += `
+### Run Component Tests with [Playwright](https://playwright.dev/docs/test-components)
+
+\`\`\`sh
+# Install browsers for the first run
+npx playwright install
+
+# Runs the component tests
+${commandFor('test:unit')}
+# Runs the tests only on Chromium
+${commandFor('test:unit', '--project=chromium')}
+# Runs the tests of a specific file
+${commandFor('test:unit', 'tests/example.spec.ts')}
+# Runs the tests in debug mode
+${commandFor('test:unit', '--debug')}
+\`\`\`
+`
+  }
+
   if (needsEslint) {
     npmScriptsDescriptions += `
 ### Lint with [ESLint](https://eslint.org/)