diff --git a/packages/api/.npmignore b/packages/api/.npmignore
index 797dab83..985ea999 100644
--- a/packages/api/.npmignore
+++ b/packages/api/.npmignore
@@ -1,12 +1,20 @@
.*
+.env
+.eslintcache
+.example.env
tsconfig*
-rollup.config.ts
jest.config.js
rollup.config.ts
yarn.lock
+**/*.spec.ts
+**/*.snap
-.tsconfig*
-
+.github
.pnp.*
+.vscode
.yarn/*
-.eslintcache
\ No newline at end of file
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/api/src/ApiEndpoint.spec.ts b/packages/api/src/spec/ApiEndpoint.spec.ts
similarity index 80%
rename from packages/api/src/ApiEndpoint.spec.ts
rename to packages/api/src/spec/ApiEndpoint.spec.ts
index 727b984b..3585b9b2 100644
--- a/packages/api/src/ApiEndpoint.spec.ts
+++ b/packages/api/src/spec/ApiEndpoint.spec.ts
@@ -1,4 +1,4 @@
-import { ApiEndpoint } from './ApiEndpoint'
+import { ApiEndpoint } from '../ApiEndpoint'
describe('ApiEndpoint', () => {
test('checking happy path', () => {
diff --git a/packages/api/src/getApiStage.spec.ts b/packages/api/src/spec/getApiStage.spec.ts
similarity index 78%
rename from packages/api/src/getApiStage.spec.ts
rename to packages/api/src/spec/getApiStage.spec.ts
index 4f8bddd2..60645995 100644
--- a/packages/api/src/getApiStage.spec.ts
+++ b/packages/api/src/spec/getApiStage.spec.ts
@@ -1,4 +1,4 @@
-import { getApiStage } from './getApiStage'
+import { getApiStage } from '../getApiStage'
describe('getApiStage', () => {
test('checking happy path', () => {
diff --git a/packages/api/src/spec/tsconfig.json b/packages/api/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/api/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/assert/.npmignore b/packages/assert/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/assert/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/bignumber/.npmignore b/packages/bignumber/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/bignumber/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/decimal-precision/.npmignore b/packages/decimal-precision/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/decimal-precision/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/delay/.npmignore b/packages/delay/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/delay/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/delay/src/delay.spec.ts b/packages/delay/src/spec/delay.spec.ts
similarity index 91%
rename from packages/delay/src/delay.spec.ts
rename to packages/delay/src/spec/delay.spec.ts
index fd35cec9..98b2603c 100644
--- a/packages/delay/src/delay.spec.ts
+++ b/packages/delay/src/spec/delay.spec.ts
@@ -1,4 +1,4 @@
-import { delay } from './delay'
+import { delay } from '../delay'
describe('delay', () => {
test('checking happy path', async () => {
diff --git a/packages/delay/src/spec/tsconfig.json b/packages/delay/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/delay/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/eth-address/.npmignore b/packages/eth-address/.npmignore
index 797dab83..985ea999 100644
--- a/packages/eth-address/.npmignore
+++ b/packages/eth-address/.npmignore
@@ -1,12 +1,20 @@
.*
+.env
+.eslintcache
+.example.env
tsconfig*
-rollup.config.ts
jest.config.js
rollup.config.ts
yarn.lock
+**/*.spec.ts
+**/*.snap
-.tsconfig*
-
+.github
.pnp.*
+.vscode
.yarn/*
-.eslintcache
\ No newline at end of file
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/eth-address/src/EthAddress.spec.ts b/packages/eth-address/src/spec/EthAddress.spec.ts
similarity index 88%
rename from packages/eth-address/src/EthAddress.spec.ts
rename to packages/eth-address/src/spec/EthAddress.spec.ts
index 9617152e..9c89b847 100644
--- a/packages/eth-address/src/EthAddress.spec.ts
+++ b/packages/eth-address/src/spec/EthAddress.spec.ts
@@ -1,4 +1,4 @@
-import { EthAddress } from './EthAddress'
+import { EthAddress } from '../EthAddress'
describe('EthAddress', () => {
test('checking happy path', () => {
diff --git a/packages/eth-address/src/spec/tsconfig.json b/packages/eth-address/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/eth-address/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/exists/.npmignore b/packages/exists/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/exists/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/exists/src/exists.spec.ts b/packages/exists/src/spec/exists.spec.ts
similarity index 96%
rename from packages/exists/src/exists.spec.ts
rename to packages/exists/src/spec/exists.spec.ts
index 973508fe..a0e627b4 100644
--- a/packages/exists/src/exists.spec.ts
+++ b/packages/exists/src/spec/exists.spec.ts
@@ -1,4 +1,4 @@
-import { exists } from './index'
+import { exists } from '../index'
const filterableValues = [undefined, null]
const nonfilterableValue = {}
diff --git a/packages/exists/src/spec/tsconfig.json b/packages/exists/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/exists/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/forget/.npmignore b/packages/forget/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/forget/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/forget/src/forget.spec.ts b/packages/forget/src/spec/forget.spec.ts
similarity index 96%
rename from packages/forget/src/forget.spec.ts
rename to packages/forget/src/spec/forget.spec.ts
index 3c09e631..3ff2b0f8 100644
--- a/packages/forget/src/forget.spec.ts
+++ b/packages/forget/src/spec/forget.spec.ts
@@ -1,6 +1,6 @@
import { delay } from '@xylabs/delay'
-import { forget, ForgetPromise } from './forget'
+import { forget, ForgetPromise } from '../forget'
describe('forget', () => {
beforeAll(() => {
diff --git a/packages/forget/src/spec/tsconfig.json b/packages/forget/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/forget/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/jest-helpers/.npmignore b/packages/jest-helpers/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/jest-helpers/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/jest-helpers/src/describeIf.spec.ts b/packages/jest-helpers/src/spec/describeIf.spec.ts
similarity index 87%
rename from packages/jest-helpers/src/describeIf.spec.ts
rename to packages/jest-helpers/src/spec/describeIf.spec.ts
index 5bcd9f02..3c5983ce 100644
--- a/packages/jest-helpers/src/describeIf.spec.ts
+++ b/packages/jest-helpers/src/spec/describeIf.spec.ts
@@ -1,4 +1,4 @@
-import { describeIf } from './describeIf'
+import { describeIf } from '../describeIf'
describe('describeIf', () => {
describeIf(true)('This block should run', () => {
diff --git a/packages/jest-helpers/src/itIf.spec.ts b/packages/jest-helpers/src/spec/itIf.spec.ts
similarity index 84%
rename from packages/jest-helpers/src/itIf.spec.ts
rename to packages/jest-helpers/src/spec/itIf.spec.ts
index 33344caf..7faa361e 100644
--- a/packages/jest-helpers/src/itIf.spec.ts
+++ b/packages/jest-helpers/src/spec/itIf.spec.ts
@@ -1,4 +1,4 @@
-import { itIf } from './itIf'
+import { itIf } from '../itIf'
describe('itIf', () => {
itIf(true)('should run', () => {
diff --git a/packages/jest-helpers/src/testIf.spec.ts b/packages/jest-helpers/src/spec/testIf.spec.ts
similarity index 83%
rename from packages/jest-helpers/src/testIf.spec.ts
rename to packages/jest-helpers/src/spec/testIf.spec.ts
index 92f4c91c..0e849d54 100644
--- a/packages/jest-helpers/src/testIf.spec.ts
+++ b/packages/jest-helpers/src/spec/testIf.spec.ts
@@ -1,4 +1,4 @@
-import { testIf } from './testIf'
+import { testIf } from '../testIf'
describe('testIf', () => {
testIf(true)('should run', () => {
diff --git a/packages/jest-helpers/src/spec/tsconfig.json b/packages/jest-helpers/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/jest-helpers/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/log/.npmignore b/packages/log/.npmignore
index 797dab83..985ea999 100644
--- a/packages/log/.npmignore
+++ b/packages/log/.npmignore
@@ -1,12 +1,20 @@
.*
+.env
+.eslintcache
+.example.env
tsconfig*
-rollup.config.ts
jest.config.js
rollup.config.ts
yarn.lock
+**/*.spec.ts
+**/*.snap
-.tsconfig*
-
+.github
.pnp.*
+.vscode
.yarn/*
-.eslintcache
\ No newline at end of file
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/log/src/Log.spec.ts b/packages/log/src/spec/Log.spec.ts
similarity index 98%
rename from packages/log/src/Log.spec.ts
rename to packages/log/src/spec/Log.spec.ts
index 9d6a6066..c9775e58 100644
--- a/packages/log/src/Log.spec.ts
+++ b/packages/log/src/spec/Log.spec.ts
@@ -1,4 +1,4 @@
-import { Log } from './Log'
+import { Log } from '../Log'
describe('Log', () => {
test('checking happy path', () => {
diff --git a/packages/log/src/spec/tsconfig.json b/packages/log/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/log/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/promise/.npmignore b/packages/promise/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/promise/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/promise/src/fulfilled.spec.ts b/packages/promise/src/spec/fulfilled.spec.ts
similarity index 95%
rename from packages/promise/src/fulfilled.spec.ts
rename to packages/promise/src/spec/fulfilled.spec.ts
index fe1d9618..bd6e81a8 100644
--- a/packages/promise/src/fulfilled.spec.ts
+++ b/packages/promise/src/spec/fulfilled.spec.ts
@@ -1,4 +1,4 @@
-import { fulfilled } from './fulfilled'
+import { fulfilled } from '../fulfilled'
const getAllResolvedPromises = () => {
return Promise.allSettled([Promise.resolve('yes')])
diff --git a/packages/promise/src/fulfilledValues.spec.ts b/packages/promise/src/spec/fulfilledValues.spec.ts
similarity index 94%
rename from packages/promise/src/fulfilledValues.spec.ts
rename to packages/promise/src/spec/fulfilledValues.spec.ts
index 849d16bc..1e61ee5e 100644
--- a/packages/promise/src/fulfilledValues.spec.ts
+++ b/packages/promise/src/spec/fulfilledValues.spec.ts
@@ -1,4 +1,4 @@
-import { fulfilledValues } from './fulfilledValues'
+import { fulfilledValues } from '../fulfilledValues'
const getAllResolvedPromises = () => {
return Promise.allSettled([Promise.resolve('yes')])
diff --git a/packages/promise/src/rejected.spec.ts b/packages/promise/src/spec/rejected.spec.ts
similarity index 95%
rename from packages/promise/src/rejected.spec.ts
rename to packages/promise/src/spec/rejected.spec.ts
index 3794a8fc..6557b4b6 100644
--- a/packages/promise/src/rejected.spec.ts
+++ b/packages/promise/src/spec/rejected.spec.ts
@@ -1,4 +1,4 @@
-import { rejected } from './rejected'
+import { rejected } from '../rejected'
const getAllResolvedPromises = () => {
return Promise.allSettled([Promise.resolve('yes')])
diff --git a/packages/promise/src/spec/tsconfig.json b/packages/promise/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/promise/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/static-implements/.depcheckrc b/packages/static-implements/.depcheckrc
new file mode 100644
index 00000000..7ae8510e
--- /dev/null
+++ b/packages/static-implements/.depcheckrc
@@ -0,0 +1,5 @@
+ignores: [
+ "jest",
+ "@xylabs/tsconfig",
+ "@xylabs/ts-scripts-yarn3"
+]
\ No newline at end of file
diff --git a/packages/static-implements/.npmignore b/packages/static-implements/.npmignore
new file mode 100644
index 00000000..985ea999
--- /dev/null
+++ b/packages/static-implements/.npmignore
@@ -0,0 +1,20 @@
+.*
+.env
+.eslintcache
+.example.env
+tsconfig*
+jest.config.js
+rollup.config.ts
+yarn.lock
+**/*.spec.ts
+**/*.snap
+
+.github
+.pnp.*
+.vscode
+.yarn/*
+coverage
+cspell.json
+node_modules
+swagger.json
+packages
\ No newline at end of file
diff --git a/packages/static-implements/LICENSE b/packages/static-implements/LICENSE
new file mode 100644
index 00000000..0a041280
--- /dev/null
+++ b/packages/static-implements/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/packages/static-implements/README.md b/packages/static-implements/README.md
new file mode 100644
index 00000000..0618fa76
--- /dev/null
+++ b/packages/static-implements/README.md
@@ -0,0 +1,71 @@
+[![logo][]](https://xylabs.com)
+
+# @xylabs/sdk-js
+
+[![main-build][]][main-build-link]
+[![beta-build][]][beta-build-link]
+[![npm-badge][]][npm-link]
+[![bch-badge][]][bch-link]
+[![codacy-badge][]][codacy-link]
+[![codeclimate-badge][]][codeclimate-link]
+[![snyk-badge][]][snyk-link]
+
+## Table of Contents
+
+- [Description](#description)
+- [Install](#install)
+- [Scripts](#scripts)
+- [Maintainers](#maintainers)
+- [License](#license)
+- [Credits](#credits)
+
+## Description
+
+SDK for base code for Typescript and Javascript Libraries.
+
+## Install
+
+Using npm:
+
+```sh
+npm i --save @xylabs/sdk-js
+```
+
+Using yarn:
+
+```sh
+yarn add @xylabs/sdk-js
+```
+
+## Scripts
+
+See [ts-scripts](https://github.com/xylabs/ts-scripts/blob/main/README.md)
+for list of shared scripts.
+
+## Maintainers
+
+- [Arie Trouw](https://github.com/arietrouw) ()
+
+## License
+
+See the [LICENSE](LICENSE) file for license details
+
+## Credits
+
+[Made with 🔥 and ❄️ by XY Labs](https://xylabs.com)
+
+[logo]: https://cdn.xy.company/img/brand/XYPersistentCompany_Logo_Icon_Colored.svg
+[main-build]: https://github.com/xylabs/sdk-js/actions/workflows/build-main.yml/badge.svg
+[main-build-link]: https://github.com/xylabs/sdk-js/actions/workflows/build-main.yml
+[beta-build]: https://github.com/xylabs/sdk-js/actions/workflows/build-beta.yml/badge.svg
+[beta-build-link]: https://github.com/xylabs/sdk-js/actions/workflows/build-beta.yml
+[npm-badge]: https://img.shields.io/npm/v/@xylabs/sdk-js.svg
+[npm-link]: https://www.npmjs.com/package/@xylabs/sdk-js
+[bch-badge]: https://bettercodehub.com/edge/badge/xylabs/sdk-js?branch=main
+[bch-link]: https://bettercodehub.com/results/xylabs/sdk-js
+[codacy-badge]: https://app.codacy.com/project/badge/Grade/c8e15e14f37741c18cfb47ac7245c698
+[codacy-link]: https://www.codacy.com/gh/xylabs/sdk-js/dashboard?utm_source=github.com&utm_medium=referral&utm_content=xylabs/sdk-js&utm_campaign=Badge_Grade
+[codeclimate-badge]: https://api.codeclimate.com/v1/badges/c5eb068f806f0b047ea7/maintainability
+[codeclimate-link]: https://codeclimate.com/github/xylabs/sdk-js/maintainability
+[snyk-badge]: https://snyk.io/test/github/xylabs/sdk-js/badge.svg?targetFile=package.json
+[snyk-link]: https://snyk.io/test/github/xylabs/sdk-js?targetFile=package.json
diff --git a/packages/static-implements/package.json b/packages/static-implements/package.json
new file mode 100644
index 00000000..1bb7dc76
--- /dev/null
+++ b/packages/static-implements/package.json
@@ -0,0 +1,60 @@
+{
+ "license": "LGPL-3.0",
+ "name": "@xylabs/static-implements",
+ "author": {
+ "email": "support@xylabs.com",
+ "name": "XY Labs Development Team",
+ "url": "https://xylabs.com"
+ },
+ "bugs": {
+ "email": "support@xylabs.com",
+ "url": "https://github.com/xylabs/sdk-js/issues"
+ },
+ "description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
+ "browser": "dist/esm/index.js",
+ "main": "dist/cjs/index.js",
+ "module": "dist/esm/index.js",
+ "docs": "dist/docs.json",
+ "types": "dist/types/index.d.ts",
+ "exports": {
+ ".": {
+ "node": {
+ "import": "./dist/esm/index.js",
+ "require": "./dist/cjs/index.js"
+ },
+ "browser": {
+ "import": "./dist/esm/index.js",
+ "require": "./dist/cjs/index.js"
+ },
+ "default": "./dist/esm/index.js"
+ },
+ "./dist/docs.json": {
+ "default": "./dist/docs.json"
+ },
+ "./package.json": "./package.json"
+ },
+ "homepage": "https://xylabs.com",
+ "keywords": [
+ "xylabs",
+ "utility",
+ "typescript",
+ "esm"
+ ],
+ "devDependencies": {
+ "@xylabs/ts-scripts-yarn3": "^2.15.0",
+ "@xylabs/tsconfig-jest": "^2.15.0",
+ "jest": "^29.4.3"
+ },
+ "peerDependencies": {
+ "jest": "*"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/xylabs/sdk-js.git"
+ },
+ "sideEffects": false,
+ "version": "2.7.1"
+}
diff --git a/packages/static-implements/src/spec/staticImplements.spec.ts b/packages/static-implements/src/spec/staticImplements.spec.ts
new file mode 100644
index 00000000..ddec63f7
--- /dev/null
+++ b/packages/static-implements/src/spec/staticImplements.spec.ts
@@ -0,0 +1,26 @@
+import { staticImplements } from '../staticImplements'
+
+interface StaticMethods {
+ foo(): string
+}
+
+@staticImplements()
+class Concrete {
+ static foo() {
+ return 'bar'
+ }
+ foo() {
+ return 1
+ }
+}
+
+describe('staticImplements', () => {
+ it('forces class to implement static methods', () => {
+ expect(Concrete.foo).toBeFunction()
+ expect(Concrete.foo()).toBeString()
+ })
+ it('does not allow instances to satisfy static constraints', () => {
+ expect(new Concrete().foo).toBeFunction()
+ expect(new Concrete().foo()).toBeNumber()
+ })
+})
diff --git a/packages/static-implements/src/spec/tsconfig.json b/packages/static-implements/src/spec/tsconfig.json
new file mode 100644
index 00000000..c867a8e0
--- /dev/null
+++ b/packages/static-implements/src/spec/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig-jest"
+}
\ No newline at end of file
diff --git a/packages/static-implements/src/staticImplements.ts b/packages/static-implements/src/staticImplements.ts
new file mode 100644
index 00000000..d8a0fdea
--- /dev/null
+++ b/packages/static-implements/src/staticImplements.ts
@@ -0,0 +1,11 @@
+/**
+ * Annotation to be used to decorate classes which support
+ * an asynchronous creation pattern
+ * @returns The decorated Module requiring it implement the members
+ * of the CreatableModule as statics properties/methods
+ */
+export function staticImplements() {
+ return (constructor: U) => {
+ constructor
+ }
+}
diff --git a/packages/static-implements/tsconfig.json b/packages/static-implements/tsconfig.json
new file mode 100644
index 00000000..83cc1081
--- /dev/null
+++ b/packages/static-implements/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationDir": "./dist/types",
+ "experimentalDecorators": true
+ },
+ "extends": "@xylabs/tsconfig"
+}
\ No newline at end of file
diff --git a/packages/static-implements/tsconfig.test.json b/packages/static-implements/tsconfig.test.json
new file mode 100644
index 00000000..fa321a7c
--- /dev/null
+++ b/packages/static-implements/tsconfig.test.json
@@ -0,0 +1,5 @@
+{
+ "exclude": ["dist/**/*"],
+ "extends": "@xylabs/tsconfig-dom",
+ "include": ["**/*.spec.ts"]
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index ae77ae97..914bce33 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2648,6 +2648,18 @@ __metadata:
languageName: unknown
linkType: soft
+"@xylabs/static-implements@workspace:packages/static-implements":
+ version: 0.0.0-use.local
+ resolution: "@xylabs/static-implements@workspace:packages/static-implements"
+ dependencies:
+ "@xylabs/ts-scripts-yarn3": ^2.15.0
+ "@xylabs/tsconfig-jest": ^2.15.0
+ jest: ^29.4.3
+ peerDependencies:
+ jest: "*"
+ languageName: unknown
+ linkType: soft
+
"@xylabs/ts-scripts-yarn3@npm:^2.15.0":
version: 2.15.0
resolution: "@xylabs/ts-scripts-yarn3@npm:2.15.0"
@@ -2749,6 +2761,17 @@ __metadata:
languageName: node
linkType: hard
+"@xylabs/tsconfig-jest@npm:^2.15.0":
+ version: 2.15.0
+ resolution: "@xylabs/tsconfig-jest@npm:2.15.0"
+ dependencies:
+ "@xylabs/tsconfig": ^2.15.0
+ peerDependencies:
+ typescript: ^4
+ checksum: 47644492194a760221d559479968cdd2beb565bfbff66cdf9e1bfea9121871e6bb5259ae05c32b6bf2f43fb05efd32ce6e21f109349597188e641bab0675d37f
+ languageName: node
+ linkType: hard
+
"@xylabs/tsconfig@npm:^2.15.0":
version: 2.15.0
resolution: "@xylabs/tsconfig@npm:2.15.0"