diff --git a/.vscode/template.code-snippets b/.vscode/template.code-snippets
new file mode 100644
index 0000000..bd851af
--- /dev/null
+++ b/.vscode/template.code-snippets
@@ -0,0 +1,15 @@
+{
+    "Gate template": {
+        "prefix": "template",
+        "body": [
+            "import { PartialTemplate } from '../types/PartialTemplate'",
+            "",
+            "/**",
+            " * The template of the ${1:and} gate",
+            " */",
+            "const ${1}Template: PartialTemplate = ${2:[]}",
+            "",
+            "export default ${1}Template"
+        ]
+    }
+}
diff --git a/src/modules/activation/types/Context.ts b/src/modules/activation/types/Context.ts
index f4576da..1283da2 100644
--- a/src/modules/activation/types/Context.ts
+++ b/src/modules/activation/types/Context.ts
@@ -4,9 +4,12 @@ import { fromSimulationState } from '../../saving/helpers/fromState'
 
 export interface Context {
     memory: Record<string, unknown>
+    getProperty: (name: string) => unknown
+    setProperty: (name: string, value: unknown) => void
     get: (index: number) => boolean
     set: (index: number, state: boolean) => void
     color: (color: string) => void
+    update: () => void
     enviroment: SimulationEnv
     colors: Record<string, string>
 }
diff --git a/src/modules/core/components/App.tsx b/src/modules/core/components/App.tsx
index 7d672f6..000ee42 100644
--- a/src/modules/core/components/App.tsx
+++ b/src/modules/core/components/App.tsx
@@ -5,7 +5,7 @@ import 'react-toastify/dist/ReactToastify.css'
 
 import { ToastContainer } from 'react-toastify'
 import { theme as muiTheme } from '../constants'
-import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
+import { Route } from 'react-router-dom'
 
 import React, { useEffect } from 'react'
 import CssBaseline from '@material-ui/core/CssBaseline'
@@ -15,6 +15,7 @@ import Head from './Head'
 import Root from './Root'
 import LogicGatePage from '../../logic-gates/components/LogicGatesPage'
 import { loadSubject } from '../subjects/loadedSubject'
+import { CustomRouter } from './CustomRouter'
 
 const App = () => {
     useEffect(() => {
@@ -27,12 +28,12 @@ const App = () => {
             <CssBaseline />
 
             <Theme theme={muiTheme}>
-                <Router>
+                <CustomRouter>
                     <Sidebar />
 
                     <Route path="/" component={Root} exact />
                     <Route path="/gates" component={LogicGatePage} />
-                </Router>
+                </CustomRouter>
             </Theme>
 
             <ToastContainer
diff --git a/src/modules/core/components/CustomRouter.tsx b/src/modules/core/components/CustomRouter.tsx
new file mode 100644
index 0000000..172ab19
--- /dev/null
+++ b/src/modules/core/components/CustomRouter.tsx
@@ -0,0 +1,6 @@
+import { BrowserRouter } from 'react-router-dom'
+import { history } from '../constants'
+
+export class CustomRouter extends BrowserRouter {
+    public history = history
+}
diff --git a/src/modules/core/components/Root.tsx b/src/modules/core/components/Root.tsx
index f997169..70f20ac 100644
--- a/src/modules/core/components/Root.tsx
+++ b/src/modules/core/components/Root.tsx
@@ -2,12 +2,14 @@ import React from 'react'
 import Canvas from './Canvas'
 import CreateSimulation from '../../create-simulation/components/CreateSimulation'
 import Input from '../../input/components/Input'
+import GateProperties from '../../logic-gates/components/GatePropertiesModal'
 
 const Root = () => {
     return (
         <>
             <Canvas />
             <CreateSimulation />
+            <GateProperties />
             <Input />
         </>
     )
diff --git a/src/modules/core/constants.ts b/src/modules/core/constants.ts
index 97ebc68..45b6b76 100644
--- a/src/modules/core/constants.ts
+++ b/src/modules/core/constants.ts
@@ -1,6 +1,7 @@
 import { createMuiTheme } from '@material-ui/core/styles'
 import { red, deepPurple } from '@material-ui/core/colors'
 import { simulationMode } from '../saving/types/SimulationSave'
+import { createBrowserHistory } from 'history'
 
 export const theme = createMuiTheme({
     palette: {
@@ -31,3 +32,8 @@ export const icons: IconInterface = {
  * The width of the sidebar
  */
 export const sidebarWidth = 240
+
+/**
+ * The history to be used by the router
+ */
+export const history = createBrowserHistory()
diff --git a/src/modules/core/styles/global-styles/mui-overrides.scss b/src/modules/core/styles/global-styles/mui-overrides.scss
index 92cfe73..73330c4 100644
--- a/src/modules/core/styles/global-styles/mui-overrides.scss
+++ b/src/modules/core/styles/global-styles/mui-overrides.scss
@@ -1,6 +1,6 @@
 @import '../colors.scss';
 
-.MuiListItem-root.contained {
+.contained {
     // i spent hours trying to find a better solution
     background-color: $primary !important;
 }
diff --git a/src/modules/logic-gates/components/GateProperties.scss b/src/modules/logic-gates/components/GateProperties.scss
new file mode 100644
index 0000000..87c2129
--- /dev/null
+++ b/src/modules/logic-gates/components/GateProperties.scss
@@ -0,0 +1,53 @@
+@import '../../core/styles/mixins/flex.scss';
+@import '../../core/styles/colors.scss';
+@import '../../core/styles/mixins/visibility.scss';
+@import '../../modals/styles/mixins/modal-container.scss';
+@import '../../modals/styles/mixins/modal-title.scss';
+
+$gate-props-margin: 1rem;
+
+#gate-properties-modal {
+    @include modal-container();
+
+    justify-content: center;
+}
+
+.visible#gate-properties-modal {
+    @include visible();
+}
+
+div #gate-properties-container {
+    @include flex;
+
+    background-color: $grey;
+    padding: $gate-props-margin * 4;
+    border-radius: 1em;
+}
+
+#gate-props-divider {
+    margin-top: $gate-props-margin;
+    margin-bottom: $gate-props-margin;
+}
+
+div #gate-props-title {
+    color: white;
+    font-size: 3em;
+}
+
+div .gate-prop-container {
+    @include flex();
+
+    flex-direction: row;
+    justify-content: start;
+}
+
+div #save-props {
+    width: 50%;
+    margin: $gate-props-margin * 2;
+    margin-bottom: 0;
+}
+
+.checkbox-label {
+    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
+        Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
diff --git a/src/modules/logic-gates/components/GatePropertiesModal.tsx b/src/modules/logic-gates/components/GatePropertiesModal.tsx
new file mode 100644
index 0000000..cc250a4
--- /dev/null
+++ b/src/modules/logic-gates/components/GatePropertiesModal.tsx
@@ -0,0 +1,138 @@
+import './GateProperties.scss'
+import React, { ChangeEvent } from 'react'
+import { getRendererSafely } from '../helpers/getRendererSafely'
+import { Property } from '../../simulation/types/GateTemplate'
+import { BehaviorSubject } from 'rxjs'
+import { useObservable } from 'rxjs-hooks'
+import Divider from '@material-ui/core/Divider'
+import TextField from '@material-ui/core/TextField'
+import CheckBox from '@material-ui/core/Checkbox'
+import { open, id } from '../subjects/LogicGatePropsSubjects'
+import { Gate } from '../../simulation/classes/Gate'
+
+export interface GatePropertyProps {
+    raw: Property
+    name: string
+    output: BehaviorSubject<string | number | boolean>
+    gate: Gate
+}
+
+/**
+ * Renders a single props of the gate
+ *
+ * @param param0 The props passed to the component
+ */
+export const GatePropery = ({ name, raw, output, gate }: GatePropertyProps) => {
+    const outputSnapshot = useObservable(() => output, '')
+
+    const displayableName = `${name[0].toUpperCase()}${name.slice(1)}:`
+
+    const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
+        const target = e.target as HTMLInputElement
+        let value: boolean | string | number = target.value
+
+        if (raw.type === 'boolean') {
+            value = target.checked
+        } else if (raw.type === 'number') {
+            value = Number(target.value)
+        }
+
+        gate.props[name] = value
+
+        if (raw.type !== 'boolean') {
+            output.next(target.value)
+        }
+
+        if (raw.needsUpdate === true) {
+            gate.update()
+        }
+    }
+
+    let input = <></>
+    if (raw.type === 'number' || raw.type === 'text') {
+        input = (
+            <TextField
+                onChange={handleChange}
+                label={displayableName}
+                value={outputSnapshot}
+                type={raw.type}
+            />
+        )
+    } else if (raw.type === 'boolean') {
+        input = (
+            <>
+                <span className="checkbox-label">{displayableName}</span>
+                <CheckBox
+                    onClick={() => {
+                        output.next(!outputSnapshot)
+                    }}
+                    onChange={handleChange}
+                    checked={!!outputSnapshot}
+                />{' '}
+            </>
+        )
+    }
+
+    return <div className="gate-prop-container">{input}</div>
+}
+
+/**
+ * The props page of any gate wich has props enabled
+ *
+ * @param props The react props of the component
+ */
+const GateProperties = () => {
+    const openSnapshot = useObservable(() => open, false)
+    const renderer = getRendererSafely()
+
+    const node = renderer.simulation.gates.get(id.value)
+
+    if (!(node && node.data && node.data.template.properties.enabled)) {
+        open.next(false)
+        return <></>
+    }
+
+    const gate = node.data
+    const gateProps = gate.props
+
+    return (
+        <div
+            id="gate-properties-modal"
+            className={openSnapshot ? 'visible' : ''}
+            onClick={() => {
+                open.next(false)
+            }}
+        >
+            <div
+                id="gate-properties-container"
+                onClick={e => {
+                    e.stopPropagation()
+                }}
+            >
+                <div id="gate-props-title">Gate properties</div>
+                <Divider id="gate-props-divider" />
+
+                {gate.template.properties.data.map((raw, index) => {
+                    const { name, base } = raw
+
+                    const prop = gateProps[name]
+                    const output = new BehaviorSubject(
+                        gateProps.hasOwnProperty(name) ? prop : base
+                    )
+
+                    return (
+                        <GatePropery
+                            output={output}
+                            raw={raw}
+                            name={name}
+                            gate={gate}
+                            key={`${index}-${id.value}-${output.value}`}
+                        />
+                    )
+                })}
+            </div>
+        </div>
+    )
+}
+
+export default GateProperties
diff --git a/src/modules/logic-gates/subjects/LogicGatePropsSubjects.ts b/src/modules/logic-gates/subjects/LogicGatePropsSubjects.ts
new file mode 100644
index 0000000..a75af4a
--- /dev/null
+++ b/src/modules/logic-gates/subjects/LogicGatePropsSubjects.ts
@@ -0,0 +1,4 @@
+import { BehaviorSubject, Subject } from 'rxjs'
+
+export const open = new Subject<boolean>()
+export const id = new BehaviorSubject<number>(0)
diff --git a/src/modules/saving/constants.ts b/src/modules/saving/constants.ts
index 4c5d5c5..92c452f 100644
--- a/src/modules/saving/constants.ts
+++ b/src/modules/saving/constants.ts
@@ -1,292 +1,32 @@
 import { GateTemplate } from '../simulation/types/GateTemplate'
 import { RendererState } from './types/SimulationSave'
+import andTemplate from './templates/and'
+import buttonTemplate from './templates/button'
+import lightTemplate from './templates/light'
+import nandTemplate from './templates/nand'
+import norTemplate from './templates/nor'
+import notTemplate from './templates/not'
+import orTemplate from './templates/or'
+import parallelDelayerTemplate from './templates/parallelDelayer'
+import rgbLightTemplate from './templates/rgb'
+import sequentialDelayerTemplate from './templates/sequentialDelayer'
+import xnorTemplate from './templates/xnor'
+import xorTemplate from './templates/xor'
 
 export const defaultSimulationName = 'default'
 export const baseTemplates: DeepPartial<GateTemplate>[] = [
-    {
-        metadata: {
-            name: 'and'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/and')
-        },
-        code: {
-            activation: `context.set(0, context.get(0) && context.get(1))`
-        },
-        pins: {
-            inputs: {
-                count: 2
-            }
-        },
-        info: ['https://en.wikipedia.org/wiki/AND_gate']
-    },
-    {
-        metadata: {
-            name: 'nand'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/nand')
-        },
-        code: {
-            activation: `context.set(0, !context.get(0) || !context.get(1))`
-        },
-        pins: {
-            inputs: {
-                count: 2
-            }
-        },
-        info: ['https://en.wikipedia.org/wiki/NAND_gate']
-    },
-    {
-        metadata: {
-            name: 'or'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/or')
-        },
-        code: {
-            activation: `context.set(0, context.get(0) || context.get(1))`
-        },
-        pins: {
-            inputs: {
-                count: 2
-            }
-        },
-        info: ['https://en.wikipedia.org/wiki/OR_gate']
-    },
-    {
-        metadata: {
-            name: 'nor'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/nor')
-        },
-        code: {
-            activation: `context.set(0, !(context.get(0) || context.get(1)))`
-        },
-        pins: {
-            inputs: {
-                count: 2
-            }
-        },
-        info: ['https://en.wikipedia.org/wiki/NOR_gate']
-    },
-    {
-        metadata: {
-            name: 'xor'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/xor')
-        },
-        code: {
-            activation: `
-            const a = context.get(0)
-            const b = context.get(1)
-            const c = (a || b) && (!a || !b)
-            
-            context.set(0, c)`
-        },
-        info: ['https://en.wikipedia.org/wiki/XOR_gate'],
-        pins: {
-            inputs: {
-                count: 2
-            }
-        }
-    },
-    {
-        metadata: {
-            name: 'xnor'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/xnor')
-        },
-        code: {
-            activation: `
-            const a = context.get(0)
-            const b = context.get(1)
-            const c = (a && b) || !(a || b)
-            
-            context.set(0, c)`
-        },
-        info: ['https://en.wikipedia.org/wiki/XNOR_gate'],
-        pins: {
-            inputs: {
-                count: 2
-            }
-        }
-    },
-    {
-        metadata: {
-            name: 'not'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/not')
-        },
-        code: {
-            activation: `context.set(0, !context.get(0))`
-        },
-        info: ['https://en.wikipedia.org/wiki/Inverter_(logic_gate)']
-    },
-    {
-        metadata: {
-            name: 'button'
-        },
-        material: {
-            fill: '#D32F2E',
-            stroke: {
-                normal: '#AB8C31',
-                active: '#7EF813'
-            },
-            colors: {
-                pressed: '#7D1313'
-            }
-        },
-        code: {
-            onClick: `
-                const old = context.memory.state
-                const state = !old
-
-                context.set(0, state)    
-                context.color(old ? context.colors.main : context.colors.pressed)
-
-                context.memory.state = state
-            `
-        },
-        pins: {
-            inputs: {
-                count: 0
-            }
-        },
-        integration: {
-            input: true
-        },
-        info: ['https://en.wikipedia.org/wiki/Push-button']
-    },
-    {
-        metadata: {
-            name: 'light bulb'
-        },
-        shape: {
-            radius: 50
-        },
-        material: {
-            fill: '#1C1C1C',
-            stroke: {
-                normal: '#3C3C3C'
-            },
-            colors: {
-                active: '#C6FF00'
-            }
-        },
-        code: {
-            activation: `
-                const { main, active } = context.colors
-
-                context.color(context.get(0) ? active : main)
-            `
-        },
-        integration: {
-            output: true
-        },
-        info: ['https://en.wikipedia.org/wiki/Incandescent_light_bulb'],
-        pins: {
-            outputs: {
-                count: 0
-            }
-        }
-    },
-    {
-        metadata: {
-            name: 'rgb light'
-        },
-        material: {
-            fill: '#1C1C1C',
-            colors: {
-                1: '#00f',
-                2: `#0f0`,
-                3: `#0ff`,
-                4: `#f00`,
-                5: `#f0f`,
-                6: `#ff0`,
-                7: `#fff`
-            }
-        },
-        code: {
-            activation: `
-                const color = (context.get(0) << 2) + (context.get(1) << 1) + context.get(2)
-
-                if (color === 0){
-                    context.color(context.colors.main)
-                }
-
-                else{
-                    context.color(context.colors[color])
-                }
-            `
-        },
-        integration: {
-            output: true
-        },
-        info: ['https://en.wikipedia.org/wiki/Incandescent_light_bulb'],
-        pins: {
-            outputs: {
-                count: 0
-            },
-            inputs: {
-                count: 3
-            }
-        }
-    },
-    {
-        metadata: {
-            name: 'Sequential delayer'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/sequential')
-        },
-        code: {
-            activation: `
-                const i = context.get(0)
-                return new Promise((res, rej) => {
-                    setTimeout(() => {
-                        res()
-                    },1000)
-                }).then(() => {
-                    context.set(0,i)
-                })
-            `,
-            async: true
-        }
-    },
-    {
-        metadata: {
-            name: 'Parallel delayer'
-        },
-        material: {
-            type: 'image',
-            fill: require('../../assets/parallel')
-        },
-        code: {
-            activation: `
-                const i = context.get(0)
-                return new Promise((res, rej) => {
-                    setTimeout(() => {
-                        res()
-                    },1000)
-                }).then(() => {
-                    context.set(0,i)
-                })
-            `
-        }
-    }
+    andTemplate,
+    buttonTemplate,
+    lightTemplate,
+    nandTemplate,
+    norTemplate,
+    notTemplate,
+    orTemplate,
+    parallelDelayerTemplate,
+    rgbLightTemplate,
+    sequentialDelayerTemplate,
+    xnorTemplate,
+    xorTemplate
 ]
 
 export const baseSave: RendererState = {
diff --git a/src/modules/saving/data/delayProperties.ts b/src/modules/saving/data/delayProperties.ts
new file mode 100644
index 0000000..e56f931
--- /dev/null
+++ b/src/modules/saving/data/delayProperties.ts
@@ -0,0 +1,12 @@
+import { GateTemplate } from '../../simulation/types/GateTemplate'
+
+export const delayProperties: GateTemplate['properties'] = {
+    enabled: true,
+    data: [
+        {
+            base: 1000,
+            type: 'number',
+            name: 'delay'
+        }
+    ]
+}
diff --git a/src/modules/saving/helpers/fromState.ts b/src/modules/saving/helpers/fromState.ts
index b935767..77d5532 100644
--- a/src/modules/saving/helpers/fromState.ts
+++ b/src/modules/saving/helpers/fromState.ts
@@ -35,7 +35,8 @@ export const fromSimulationState = (
     for (const gateState of state.gates) {
         const gate = new Gate(
             templateStore.get(gateState.template),
-            gateState.id
+            gateState.id,
+            gateState.props
         )
         gate.transform = fromTransformState(gateState.transform)
 
diff --git a/src/modules/saving/templates/and.ts b/src/modules/saving/templates/and.ts
new file mode 100644
index 0000000..ba8636d
--- /dev/null
+++ b/src/modules/saving/templates/and.ts
@@ -0,0 +1,25 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the and gate
+ */
+const andTemplate: PartialTemplate = {
+    metadata: {
+        name: 'and'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/and')
+    },
+    code: {
+        activation: `context.set(0, context.get(0) && context.get(1))`
+    },
+    pins: {
+        inputs: {
+            count: 2
+        }
+    },
+    info: ['https://en.wikipedia.org/wiki/AND_gate']
+}
+
+export default andTemplate
diff --git a/src/modules/saving/templates/button.ts b/src/modules/saving/templates/button.ts
new file mode 100644
index 0000000..a8e1e8d
--- /dev/null
+++ b/src/modules/saving/templates/button.ts
@@ -0,0 +1,56 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the button gate
+ */
+const buttonTemplate: PartialTemplate = {
+    metadata: {
+        name: 'button'
+    },
+    material: {
+        fill: '#D32F2E',
+        stroke: {
+            normal: '#AB8C31',
+            active: '#7EF813'
+        },
+        colors: {
+            pressed: '#7D1313'
+        }
+    },
+    code: {
+        onClick: `
+            const active = context.getProperty('active')
+            context.setProperty('active',!active)
+
+            context.update()
+        `,
+        activation: `
+            const state = context.getProperty('active')
+
+            context.set(0, state)    
+            context.color(!state ? context.colors.main : context.colors.pressed)
+        `
+    },
+    pins: {
+        inputs: {
+            count: 0
+        }
+    },
+    integration: {
+        input: true
+    },
+    info: ['https://en.wikipedia.org/wiki/Push-button'],
+    properties: {
+        enabled: true,
+        data: [
+            {
+                base: false,
+                name: 'active',
+                type: 'boolean',
+                needsUpdate: true
+            }
+        ]
+    }
+}
+
+export default buttonTemplate
diff --git a/src/modules/saving/templates/light.ts b/src/modules/saving/templates/light.ts
new file mode 100644
index 0000000..c01a357
--- /dev/null
+++ b/src/modules/saving/templates/light.ts
@@ -0,0 +1,40 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the light gate
+ */
+const lightTemplate: PartialTemplate = {
+    metadata: {
+        name: 'light bulb'
+    },
+    shape: {
+        radius: 50
+    },
+    material: {
+        fill: '#1C1C1C',
+        stroke: {
+            normal: '#3C3C3C'
+        },
+        colors: {
+            active: '#C6FF00'
+        }
+    },
+    code: {
+        activation: `
+            const { main, active } = context.colors
+
+            context.color(context.get(0) ? active : main)
+        `
+    },
+    integration: {
+        output: true
+    },
+    info: ['https://en.wikipedia.org/wiki/Incandescent_light_bulb'],
+    pins: {
+        outputs: {
+            count: 0
+        }
+    }
+}
+
+export default lightTemplate
diff --git a/src/modules/saving/templates/nand.ts b/src/modules/saving/templates/nand.ts
new file mode 100644
index 0000000..08cdf36
--- /dev/null
+++ b/src/modules/saving/templates/nand.ts
@@ -0,0 +1,25 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the nand gate
+ */
+const nandTemplate: PartialTemplate = {
+    metadata: {
+        name: 'nand'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/nand')
+    },
+    code: {
+        activation: `context.set(0, !context.get(0) || !context.get(1))`
+    },
+    pins: {
+        inputs: {
+            count: 2
+        }
+    },
+    info: ['https://en.wikipedia.org/wiki/NAND_gate']
+}
+
+export default nandTemplate
diff --git a/src/modules/saving/templates/nor.ts b/src/modules/saving/templates/nor.ts
new file mode 100644
index 0000000..3a57108
--- /dev/null
+++ b/src/modules/saving/templates/nor.ts
@@ -0,0 +1,25 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the nor gate
+ */
+const norTemplate: PartialTemplate = {
+    metadata: {
+        name: 'nor'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/nor')
+    },
+    code: {
+        activation: `context.set(0, !(context.get(0) || context.get(1)))`
+    },
+    pins: {
+        inputs: {
+            count: 2
+        }
+    },
+    info: ['https://en.wikipedia.org/wiki/NOR_gate']
+}
+
+export default norTemplate
diff --git a/src/modules/saving/templates/not.ts b/src/modules/saving/templates/not.ts
new file mode 100644
index 0000000..485ddce
--- /dev/null
+++ b/src/modules/saving/templates/not.ts
@@ -0,0 +1,20 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the not gate
+ */
+const notTemplate: PartialTemplate = {
+    metadata: {
+        name: 'not'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/not')
+    },
+    code: {
+        activation: `context.set(0, !context.get(0))`
+    },
+    info: ['https://en.wikipedia.org/wiki/Inverter_(logic_gate)']
+}
+
+export default notTemplate
diff --git a/src/modules/saving/templates/or.ts b/src/modules/saving/templates/or.ts
new file mode 100644
index 0000000..dc9c80a
--- /dev/null
+++ b/src/modules/saving/templates/or.ts
@@ -0,0 +1,25 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the or gate
+ */
+const orTemplate: PartialTemplate = {
+    metadata: {
+        name: 'or'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/or')
+    },
+    code: {
+        activation: `context.set(0, context.get(0) || context.get(1))`
+    },
+    pins: {
+        inputs: {
+            count: 2
+        }
+    },
+    info: ['https://en.wikipedia.org/wiki/OR_gate']
+}
+
+export default orTemplate
diff --git a/src/modules/saving/templates/parallelDelayer.ts b/src/modules/saving/templates/parallelDelayer.ts
new file mode 100644
index 0000000..6e50c83
--- /dev/null
+++ b/src/modules/saving/templates/parallelDelayer.ts
@@ -0,0 +1,30 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+import { delayProperties } from '../data/delayProperties'
+
+/**
+ * The template of the parallelDelayer gate
+ */
+const parallelDelayerTemplate: PartialTemplate = {
+    metadata: {
+        name: 'Parallel delayer'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/parallel')
+    },
+    code: {
+        activation: `
+            const i = context.get(0)
+            return new Promise((res, rej) => {
+                setTimeout(() => {
+                    res()
+                }, context.getProperty('delay'))
+            }).then(() => {
+                context.set(0,i)
+            })
+        `
+    },
+    properties: delayProperties
+}
+
+export default parallelDelayerTemplate
diff --git a/src/modules/saving/templates/rgb.ts b/src/modules/saving/templates/rgb.ts
new file mode 100644
index 0000000..8fe0c05
--- /dev/null
+++ b/src/modules/saving/templates/rgb.ts
@@ -0,0 +1,49 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the rgbLight gate
+ */
+const rgbLightTemplate: PartialTemplate = {
+    metadata: {
+        name: 'rgb light'
+    },
+    material: {
+        fill: '#1C1C1C',
+        colors: {
+            1: '#00f',
+            2: `#0f0`,
+            3: `#0ff`,
+            4: `#f00`,
+            5: `#f0f`,
+            6: `#ff0`,
+            7: `#fff`
+        }
+    },
+    code: {
+        activation: `
+            const color = (context.get(0) << 2) + (context.get(1) << 1) + context.get(2)
+
+            if (color === 0){
+                context.color(context.colors.main)
+            }
+
+            else{
+                context.color(context.colors[color])
+            }
+        `
+    },
+    integration: {
+        output: true
+    },
+    info: ['https://en.wikipedia.org/wiki/Incandescent_light_bulb'],
+    pins: {
+        outputs: {
+            count: 0
+        },
+        inputs: {
+            count: 3
+        }
+    }
+}
+
+export default rgbLightTemplate
diff --git a/src/modules/saving/templates/sequentialDelayer.ts b/src/modules/saving/templates/sequentialDelayer.ts
new file mode 100644
index 0000000..d6519e1
--- /dev/null
+++ b/src/modules/saving/templates/sequentialDelayer.ts
@@ -0,0 +1,31 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+import { delayProperties } from '../data/delayProperties'
+
+/**
+ * The template of the sequentialDelayer gate
+ */
+const sequentialDelayerTemplate: PartialTemplate = {
+    metadata: {
+        name: 'Sequential delayer'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/sequential')
+    },
+    code: {
+        activation: `
+            const i = context.get(0)
+            return new Promise((res, rej) => {
+                setTimeout(() => {
+                    res()
+                },context.getProperty('delay'))
+            }).then(() => {
+                context.set(0,i)
+            })
+        `,
+        async: true
+    },
+    properties: delayProperties
+}
+
+export default sequentialDelayerTemplate
diff --git a/src/modules/saving/templates/xnor.ts b/src/modules/saving/templates/xnor.ts
new file mode 100644
index 0000000..978bc5a
--- /dev/null
+++ b/src/modules/saving/templates/xnor.ts
@@ -0,0 +1,30 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the xnor gate
+ */
+const xnorTemplate: PartialTemplate = {
+    metadata: {
+        name: 'xnor'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/xnor')
+    },
+    code: {
+        activation: `
+        const a = context.get(0)
+        const b = context.get(1)
+        const c = (a && b) || !(a || b)
+        
+        context.set(0, c)`
+    },
+    info: ['https://en.wikipedia.org/wiki/XNOR_gate'],
+    pins: {
+        inputs: {
+            count: 2
+        }
+    }
+}
+
+export default xnorTemplate
diff --git a/src/modules/saving/templates/xor.ts b/src/modules/saving/templates/xor.ts
new file mode 100644
index 0000000..5d96ecb
--- /dev/null
+++ b/src/modules/saving/templates/xor.ts
@@ -0,0 +1,30 @@
+import { PartialTemplate } from '../types/PartialTemplate'
+
+/**
+ * The template of the xor gate
+ */
+const xorTemplate: PartialTemplate = {
+    metadata: {
+        name: 'xor'
+    },
+    material: {
+        type: 'image',
+        fill: require('../../../assets/xor')
+    },
+    code: {
+        activation: `
+        const a = context.get(0)
+        const b = context.get(1)
+        const c = (a || b) && (!a || !b)
+        
+        context.set(0, c)`
+    },
+    info: ['https://en.wikipedia.org/wiki/XOR_gate'],
+    pins: {
+        inputs: {
+            count: 2
+        }
+    }
+}
+
+export default xorTemplate
diff --git a/src/modules/saving/types/PartialTemplate.ts b/src/modules/saving/types/PartialTemplate.ts
new file mode 100644
index 0000000..803fae5
--- /dev/null
+++ b/src/modules/saving/types/PartialTemplate.ts
@@ -0,0 +1,6 @@
+import { GateTemplate } from '../../simulation/types/GateTemplate'
+
+/**
+ * Deep partial of a gate template
+ */
+export type PartialTemplate = DeepPartial<GateTemplate>
diff --git a/src/modules/saving/types/SimulationSave.ts b/src/modules/saving/types/SimulationSave.ts
index 9a502c2..1d58e7a 100644
--- a/src/modules/saving/types/SimulationSave.ts
+++ b/src/modules/saving/types/SimulationSave.ts
@@ -12,7 +12,7 @@ export interface GateState {
     transform: TransformState
     id: number
     template: string
-    props: Record<string, unknown>
+    props: Record<string, string | number | boolean>
 }
 
 export interface CameraState {
diff --git a/src/modules/simulation/classes/Gate.ts b/src/modules/simulation/classes/Gate.ts
index 734489e..fe2b284 100644
--- a/src/modules/simulation/classes/Gate.ts
+++ b/src/modules/simulation/classes/Gate.ts
@@ -118,7 +118,7 @@ export class Gate {
     /**
      * The props used by the activation function (the same as memory but presists)
      */
-    public props: Record<string, unknown> = {}
+    public props: Record<string, string | number | boolean> = {}
 
     /**
      * The main logic gate class
@@ -129,7 +129,7 @@ export class Gate {
     public constructor(
         template: DeepPartial<GateTemplate> = {},
         id?: number,
-        props: Record<string, unknown> = {}
+        props: Record<string, string> = {}
     ) {
         this.template = completeTemplate(template)
 
@@ -259,17 +259,25 @@ export class Gate {
     /**
      * Assign the props passed to the gate and mere them with the base ones
      */
-    private assignProps(props: Record<string, unknown>) {
+    private assignProps(props: Record<string, string>) {
+        let shouldUpdate = false
+
         if (this.template.properties.enabled) {
-            for (const prop in this.template.properties) {
-                if (prop !== 'enabled') {
-                    this.props[prop] =
-                        props[prop] !== undefined
-                            ? props[prop]
-                            : this.template.properties[prop].base
+            for (const { base, name, needsUpdate } of this.template.properties
+                .data) {
+                this.props[name] = props.hasOwnProperty(name)
+                    ? props[name]
+                    : base
+
+                if (!shouldUpdate && needsUpdate) {
+                    shouldUpdate = true
                 }
             }
         }
+
+        if (shouldUpdate) {
+            this.update()
+        }
     }
 
     /**
@@ -335,13 +343,22 @@ export class Gate {
             set: (index: number, state: boolean = false) => {
                 return this._pins.outputs[index].state.next(state)
             },
-            memory: this.memory,
             color: (color: string) => {
                 if (this.template.material.type === 'color') {
                     this.template.material.fill = color
                 }
             },
+            getProperty: (name: string) => {
+                return this.props[name]
+            },
+            setProperty: (name: string, value: string | number | boolean) => {
+                this.props[name] = value
+            },
+            update: () => {
+                this.update()
+            },
             enviroment: this.env,
+            memory: this.memory,
             colors: {
                 ...this.template.material.colors
             }
diff --git a/src/modules/simulation/classes/Wire.ts b/src/modules/simulation/classes/Wire.ts
index 65ac442..d4e0d9a 100644
--- a/src/modules/simulation/classes/Wire.ts
+++ b/src/modules/simulation/classes/Wire.ts
@@ -30,6 +30,7 @@ export class Wire {
     public dispose() {
         this.end.value.removePair(this.start.value)
         this.start.value.removePair(this.end.value)
+        this.end.value.state.next(false)
 
         this.active = false
     }
diff --git a/src/modules/simulation/constants.ts b/src/modules/simulation/constants.ts
index 39062ab..77b66be 100644
--- a/src/modules/simulation/constants.ts
+++ b/src/modules/simulation/constants.ts
@@ -51,6 +51,7 @@ export const DefaultGateTemplate: GateTemplate = {
     info: [],
     tags: ['base'],
     properties: {
-        enabled: false
+        enabled: false,
+        data: []
     }
 }
diff --git a/src/modules/simulation/types/GateTemplate.ts b/src/modules/simulation/types/GateTemplate.ts
index 24ceec1..ab089da 100644
--- a/src/modules/simulation/types/GateTemplate.ts
+++ b/src/modules/simulation/types/GateTemplate.ts
@@ -1,15 +1,17 @@
 import { vector2 } from '../../../common/math/classes/Transform'
-import { InputHTMLAttributes } from 'react'
 
 export interface PinCount {
     variable: boolean
     count: number
 }
 
-export interface Property<T> {
-    type: HTMLInputElement['type']
-    encode: (value: string) => T
+export interface Property<
+    T extends boolean | number | string = boolean | number | string
+> {
+    type: 'number' | 'string' | 'text' | 'boolean'
     base: T
+    name: string
+    needsUpdate?: boolean
 }
 
 export interface Material {
@@ -69,5 +71,8 @@ export interface GateTemplate {
     }
     info: string[]
     tags: GateTag[]
-    properties: Enabled<Record<Exclude<string, 'enabled'>, Property<unknown>>>
+    properties: {
+        enabled: boolean
+        data: Property[]
+    }
 }
diff --git a/src/modules/simulationRenderer/classes/SimulationRenderer.ts b/src/modules/simulationRenderer/classes/SimulationRenderer.ts
index 68c0d0a..332b95c 100644
--- a/src/modules/simulationRenderer/classes/SimulationRenderer.ts
+++ b/src/modules/simulationRenderer/classes/SimulationRenderer.ts
@@ -35,6 +35,10 @@ import { gatesInSelection } from '../helpers/gatesInSelection'
 import { selectionType } from '../types/selectionType'
 import { addIdToSelection, idIsSelected } from '../helpers/idIsSelected'
 import { GateInitter } from '../types/GateInitter'
+import {
+    open as propsAreOpen,
+    id as propsModalId
+} from '../../logic-gates/subjects/LogicGatePropsSubjects'
 
 export class SimulationRenderer {
     public mouseDownOutput = new Subject<MouseEventInfo>()
@@ -89,29 +93,34 @@ export class SimulationRenderer {
             // because if we have 2 overlapping gates,
             // we want to select the one on top
             for (let index = gates.length - 1; index >= 0; index--) {
-                const { transform, id, pins } = gates[index]
+                const { transform, id, pins, template } = gates[index]
 
-                if (
-                    event.button === mouseButtons.drag &&
-                    pointInSquare(worldPosition, transform)
-                ) {
-                    gates[index].onClick()
+                if (pointInSquare(worldPosition, transform)) {
+                    if (event.button === mouseButtons.drag) {
+                        gates[index].onClick()
 
-                    this.mouseState |= 1
+                        this.mouseState |= 1
 
-                    if (!idIsSelected(this, id)) {
-                        this.clearSelection()
-                        addIdToSelection(this, 'temporary', id)
-                    }
+                        if (!idIsSelected(this, id)) {
+                            this.clearSelection()
+                            addIdToSelection(this, 'temporary', id)
+                        }
 
-                    const gateNode = this.simulation.gates.get(id)
+                        const gateNode = this.simulation.gates.get(id)
 
-                    if (gateNode) {
-                        return this.simulation.gates.moveOnTop(gateNode)
-                    } else {
-                        throw new SimulationError(
-                            `Cannot find gate with id ${id}`
-                        )
+                        if (gateNode) {
+                            return this.simulation.gates.moveOnTop(gateNode)
+                        } else {
+                            throw new SimulationError(
+                                `Cannot find gate with id ${id}`
+                            )
+                        }
+                    } else if (
+                        event.button === mouseButtons.properties &&
+                        template.properties.enabled
+                    ) {
+                        propsModalId.next(id)
+                        return propsAreOpen.next(true)
                     }
                 }
 
@@ -313,21 +322,15 @@ export class SimulationRenderer {
     }
 
     public reloadSave() {
-        try {
-            dumpSimulation(this)
+        dumpSimulation(this)
 
-            const current = currentStore.get()
-            const save = saveStore.get(current)
+        const current = currentStore.get()
+        const save = saveStore.get(current)
 
-            if (!save) return
-            if (!(save.simulation || save.camera)) return
+        if (!save) return
+        if (!(save.simulation || save.camera)) return
 
-            this.loadSave(save)
-        } catch (e) {
-            throw new Error(
-                `An error occured while loading the save: ${e as Error}`
-            )
-        }
+        this.loadSave(save)
     }
 
     /**
diff --git a/src/modules/simulationRenderer/constants.ts b/src/modules/simulationRenderer/constants.ts
index cf9b32f..342c716 100644
--- a/src/modules/simulationRenderer/constants.ts
+++ b/src/modules/simulationRenderer/constants.ts
@@ -37,15 +37,13 @@ export const defaultSimulationRendererOptions: SimulationRendererOptions = {
 
 export const imageQuality: vector2 = [100, 100]
 
-export const mouseButtons: Record<
-    'zoom' | 'pan' | 'drag' | 'select' | 'unselect',
-    mouseButton
-> = {
+export const mouseButtons = {
     zoom: 1,
     drag: 0,
     pan: 2,
     select: 0,
-    unselect: 0
+    unselect: 0,
+    properties: 2
 }
 
 export const shiftInput = new KeyboardInput('shift')