diff --git a/README.md b/README.md
index ace984a7..cecb7347 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,7 @@ all vendor code in the vendor directory, and not requiring custom installer code
| Eliasis | `eliasis-component`
`eliasis-module`
`eliasis-plugin`
`eliasis-template`
| ExpressionEngine 3 | `ee3-addon`
`ee3-theme`
| eZ Platform | `ezplatform-assets`
`ezplatform-meta-assets`
+| ForkCMS ^v6.x| `fork-cms-module`
`fork-cms-theme`
| FuelPHP v1.x | `fuel-module`
`fuel-package`
`fuel-theme`
| FuelPHP v2.x | `fuelphp-component`
| Grav | `grav-plugin`
`grav-theme`
diff --git a/src/Composer/Installers/ForkCMSInstaller.php b/src/Composer/Installers/ForkCMSInstaller.php
new file mode 100644
index 00000000..cf629267
--- /dev/null
+++ b/src/Composer/Installers/ForkCMSInstaller.php
@@ -0,0 +1,58 @@
+ */
+ protected $locations = [
+ 'module' => 'src/Modules/{$name}/',
+ 'theme' => 'src/Themes/{$name}/'
+ ];
+
+ /**
+ * Format package name.
+ *
+ * For package type fork-cms-module, cut off a trailing '-plugin' if present.
+ *
+ * For package type fork-cms-theme, cut off a trailing '-theme' if present.
+ */
+ public function inflectPackageVars(array $vars): array
+ {
+ if ($vars['type'] === 'fork-cms-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'fork-cms-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ /**
+ * @param array $vars
+ * @return array
+ */
+ protected function inflectModuleVars(array $vars): array
+ {
+ $vars['name'] = $this->pregReplace('/^fork-cms-|-module|ForkCMS|ForkCms|Forkcms|forkcms|Module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make module name camelcased
+
+ return $vars;
+ }
+
+ /**
+ * @param array $vars
+ * @return array
+ */
+ protected function inflectThemeVars(array $vars): array
+ {
+ $vars['name'] = $this->pregReplace('/^fork-cms-|-theme|ForkCMS|ForkCms|Forkcms|forkcms|Theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make theme name camelcased
+
+ return $vars;
+ }
+}
diff --git a/src/Composer/Installers/Installer.php b/src/Composer/Installers/Installer.php
index 67a73e9d..e0c21122 100644
--- a/src/Composer/Installers/Installer.php
+++ b/src/Composer/Installers/Installer.php
@@ -45,6 +45,7 @@ class Installer extends LibraryInstaller
'ee3' => 'ExpressionEngineInstaller',
'ee2' => 'ExpressionEngineInstaller',
'ezplatform' => 'EzPlatformInstaller',
+ 'fork' => 'ForkCMSInstaller',
'fuel' => 'FuelInstaller',
'fuelphp' => 'FuelphpInstaller',
'grav' => 'GravInstaller',
diff --git a/tests/Composer/Installers/Test/ForkCMSInstallerTest.php b/tests/Composer/Installers/Test/ForkCMSInstallerTest.php
new file mode 100644
index 00000000..fb694171
--- /dev/null
+++ b/tests/Composer/Installers/Test/ForkCMSInstallerTest.php
@@ -0,0 +1,300 @@
+installer = new ForkCMSInstaller(
+ new Package('Knife', '4.2', '4.2'),
+ $this->getComposer(),
+ $this->getMockIO()
+ );
+ }
+
+ /**
+ * @dataProvider packageNameInflectionProvider
+ */
+ public function testInflectPackageVars(string $type, string $vendor, string $name, string $expectedVendor, string $expectedName): void
+ {
+ $this->assertEquals(
+ $this->installer->inflectPackageVars([
+ 'vendor' => $vendor,
+ 'name' => $name,
+ 'type' => $type
+ ]),
+ ['vendor' => $expectedVendor, 'name' => $expectedName, 'type' => $type]
+ );
+ }
+
+ public function packageNameInflectionProvider(): array
+ {
+ return [
+ // module with lowercase name
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife',
+ 'pageon',
+ 'Knife',
+ ],
+ // theme with lowercase name
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife',
+ 'pageon',
+ 'Knife',
+ ],
+ // module with lowercase name and module affix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife-module',
+ 'pageon',
+ 'Knife',
+ ],
+ // theme with lowercase name and theme affix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife-theme',
+ 'pageon',
+ 'Knife',
+ ],
+ // module with lowercase name and module affix and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife-module',
+ 'pageon',
+ 'Knife',
+ ],
+ // theme with lowercase name and theme affix and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife-theme',
+ 'pageon',
+ 'Knife',
+ ],
+ // module with lowercase name and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife',
+ 'pageon',
+ 'Knife',
+ ],
+ // theme with lowercase name and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife',
+ 'pageon',
+ 'Knife',
+ ],
+ // module with hyphenated name
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife-and-spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with hyphenated name
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife-and-spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with hyphenated name and module affix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife-and-spoon-module',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with hyphenated name and theme affix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife-and-spoon-theme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with hyphenated name and module affix and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife-and-spoon-module',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with hyphenated name and theme affix and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife-and-spoon-theme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with hyphenated name and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife-and-spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with hyphenated name and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife-and-spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with underscored name
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife_and_spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with underscored name
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife_and_spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with underscored name and module affix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knife_and_spoon-module',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with underscored name and theme affix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knife_and_spoon-theme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with underscored name and module affix and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife_and_spoon-module',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with underscored name and theme affix and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife_and_spoon-theme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with underscored name and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'fork-cms-knife_and_spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with underscored name and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'fork-cms-knife_and_spoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with camelcased name
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knifeAndSpoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with camelcased name
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knifeAndSpoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with camelcased name and module affix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'knifeAndSpoonModule',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with camelcased name and theme affix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'knifeAndSpoonTheme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with camelcased name and module affix and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'ForkCmsKnifeAndSpoonModule',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with camelcased name and theme affix and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'ForkCmsKnifeAndSpoonTheme',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // module with camelcased name and fork-cms prefix
+ [
+ 'fork-cms-module',
+ 'pageon',
+ 'ForkCmsKnifeAndSpoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ // theme with camelcased name and fork-cms prefix
+ [
+ 'fork-cms-theme',
+ 'pageon',
+ 'ForkCmsKnifeAndSpoon',
+ 'pageon',
+ 'KnifeAndSpoon',
+ ],
+ ];
+ }
+}