diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
new file mode 100644
index 0000000..9b28fd8
--- /dev/null
+++ b/.github/workflows/ci-cd.yml
@@ -0,0 +1,80 @@
+name: CI/CD
+
+on:
+    workflow_dispatch: # Allows you to run this workflow manually from the Actions tab
+    pull_request: # Runs whenever a pull request is created or updated
+    push: # Runs whenever a commit is pushed to the repository
+        branches: [master, develop, hotfix/*]
+
+concurrency:
+    group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
+    cancel-in-progress: true
+
+permissions:
+    contents: write # publish a GitHub release
+    pages: write # deploy to GitHub Pages
+    issues: write # comment on released issues
+    pull-requests: write # comment on released pull requests
+
+jobs:
+    ci-cd:
+        runs-on: ubuntu-latest
+        env:
+            TRIGGER_DEPLOY: ${{ startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/heads/hotfix') || startsWith(github.ref, 'refs/heads/develop') || startsWith(github.ref, 'refs/heads/beta') }}
+        steps:
+            - uses: actions/checkout@v4
+            - uses: wagoid/commitlint-github-action@v5
+              if: github.event_name == 'pull_request'
+            - uses: actions/setup-node@v3
+              with:
+                  cache: "npm"
+                  node-version-file: ".nvmrc"
+
+            - name: Info
+              run: |
+                  cat <<EOF
+                  Node version: $(node --version)
+                  NPM version: $(npm --version)
+                  GitHub ref: ${{ github.ref }}
+                  GitHub head ref: ${{ github.head_ref }}
+                  EOF
+
+            - name: Setup & Test
+              run: |
+                  npm ci
+                  npm run test
+
+            - name: Generate release version
+              run: |
+                  export NODE_ENV=production
+                  export RELEASE_TIMESTAMP=$(date +'%Y%m%d%H%M%S')
+                  export VPKG=$($(npm bin)/json -f package.json version)
+                  export VERSION=${VPKG}-prerelease.${RELEASE_TIMESTAMP}
+                  echo "RELEASE_VERSION=${VERSION}" >> $GITHUB_ENV
+                  if [[ "${GITHUB_REF##*/}" == hotfix/*  ]]; then
+                    echo "NPM_TAG=hotfix" >> $GITHUB_ENV
+                  else
+                    echo "NPM_TAG=latest" >> $GITHUB_ENV
+                  fi
+
+            - name: Build
+              run: |
+                  npm run build
+                  npm --no-git-tag-version version $RELEASE_VERSION
+
+            - name: Deploy to NPM (do a dry-run if not on master, develop, or hotfix/*)
+              env:
+                  NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+                  NPM_TAG: ${{ env.NPM_TAG }}
+              run: |
+                  message=$([[ "$TRIGGER_DEPLOY" == "false" ]] && echo "DRY RUN of" || echo "Deploying")
+                  echo "$message version $RELEASE_VERSION to $NPM_TAG"
+                  npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN
+                  npm publish --tag $NPM_TAG $([[ "$TRIGGER_DEPLOY" == "false" ]] && echo "--dry-run")
+
+            - name: Check Release Version and Create Tag
+              run: |
+                  if npm info | grep -q $RELEASE_VERSION; then 
+                    git tag $RELEASE_VERSION 
+                    git push origin $RELEASE_VERSION
+                  fi
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..6f7f377
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+v16