diff --git a/src/lib/_misc/_utils.ts b/src/lib/_misc/_utils.ts
new file mode 100644
index 0000000..6ceabdf
--- /dev/null
+++ b/src/lib/_misc/_utils.ts
@@ -0,0 +1,48 @@
+export type EventHandlers = Pick<
+ Input,
+ {
+ [K in keyof Input]: K extends `on${infer A}`
+ ? keyof Input & `on${A}`
+ : never;
+ }[keyof Input]
+>;
+
+export type ExtractMap<
+ Obj extends Record,
+ Key extends Exclude = never,
+> = Obj['*'][keyof Obj['*']] &
+ (Obj[Key] extends never ? '' : Obj[Key][keyof Obj[Key]]);
+
+export type ExtractString<
+ Obj extends Record,
+ Key extends keyof Obj,
+> = Obj[Key][keyof Obj[Key]];
+
+export type HTMLElementsMap = Record<
+ '*' | keyof HTMLElementTagNameMap,
+ readonly string[]
+>;
+
+export type IfThen = (() => T extends A
+ ? 1
+ : 2) extends () => T extends B ? 1 : 2
+ ? Then
+ : Else;
+
+export type WritableProps = {
+ [Prop in keyof Obj]: IfThen<
+ {
+ [K in Prop]: Obj[Prop];
+ },
+ { -readonly [K in Prop]: Obj[Prop] },
+ Prop
+ >;
+}[keyof Obj];
+
+export type FunctionProps = {
+ [Prop in keyof Obj]: Obj[Prop] extends Function ? Prop : never;
+}[keyof Obj];
+
+export type EventProps = {
+ [K in keyof Obj]: K extends `on${infer A}` ? keyof Obj & `on${A}` : never;
+}[keyof Obj];
diff --git a/src/lib/_misc/html-element-attributes.ts b/src/lib/_misc/html-element-attributes.ts
new file mode 100644
index 0000000..079746d
--- /dev/null
+++ b/src/lib/_misc/html-element-attributes.ts
@@ -0,0 +1,152 @@
+import { HTMLElementsMap } from '../types/_utils';
+
+const htmlElementAttributes: HTMLElementsMap = {
+ '*': [
+ 'accesskey',
+ 'autocapitalize',
+ 'autofocus',
+ 'class',
+ 'contenteditable',
+ 'data-*',
+ 'dir',
+ 'draggable',
+ 'enterkeyhint',
+ 'hidden',
+ 'id',
+ 'inputmode',
+ 'is',
+ 'itemid',
+ 'itemprop',
+ 'itemref',
+ 'itemscope',
+ 'itemtype',
+ 'lang',
+ 'nonce',
+ 'part',
+ 'slot',
+ 'spellcheck',
+ 'style',
+ 'tabindex',
+ 'title',
+ 'translate',
+ ],
+ a: [],
+ abbr: [],
+ address: [],
+ area: [],
+ article: [],
+ aside: [],
+ audio: [],
+ b: [],
+ base: [],
+ bdi: [],
+ bdo: [],
+ blockquote: [],
+ body: [],
+ br: [],
+ button: [],
+ canvas: [],
+ caption: [],
+ cite: [],
+ code: [],
+ col: [],
+ colgroup: [],
+ data: [],
+ datalist: [],
+ dd: [],
+ del: [],
+ details: [],
+ dfn: [],
+ dialog: [],
+ dir: [],
+ div: [],
+ dl: [],
+ dt: [],
+ em: [],
+ embed: [],
+ fieldset: [],
+ figcaption: [],
+ figure: [],
+ font: [],
+ footer: [],
+ form: [],
+ frame: [],
+ frameset: [],
+ h1: [],
+ h2: [],
+ h3: [],
+ h4: [],
+ h5: [],
+ h6: [],
+ head: [],
+ header: [],
+ hgroup: [],
+ hr: [],
+ html: [],
+ i: [],
+ iframe: [],
+ img: [],
+ input: [],
+ ins: [],
+ kbd: [],
+ label: [],
+ legend: [],
+ li: [],
+ link: [],
+ main: [],
+ map: [],
+ mark: [],
+ marquee: [],
+ menu: [],
+ meta: [],
+ meter: [],
+ nav: [],
+ noscript: [],
+ object: [],
+ ol: [],
+ optgroup: [],
+ option: [],
+ output: [],
+ p: [],
+ param: [],
+ picture: [],
+ pre: [],
+ progress: [],
+ q: [],
+ rp: [],
+ rt: [],
+ ruby: [],
+ s: [],
+ samp: [],
+ script: [],
+ section: [],
+ select: [],
+ slot: [],
+ small: [],
+ source: [],
+ span: [],
+ strong: [],
+ style: [],
+ sub: [],
+ summary: [],
+ sup: [],
+ table: [],
+ tbody: [],
+ td: [],
+ template: [],
+ textarea: [],
+ tfoot: [],
+ th: [],
+ thead: [],
+ time: [],
+ title: [],
+ tr: [],
+ track: [],
+ u: [],
+ ul: [],
+ var: [],
+ video: [],
+ wbr: [],
+} as const;
+
+export default htmlElementAttributes;
diff --git a/src/lib/_misc/html-element-events.ts b/src/lib/_misc/html-element-events.ts
new file mode 100644
index 0000000..1e0bc16
--- /dev/null
+++ b/src/lib/_misc/html-element-events.ts
@@ -0,0 +1,207 @@
+import {
+ EventHandlers,
+ ExtractMap,
+ ExtractString,
+ HTMLElementsMap,
+} from '../types/_utils';
+
+type SpecificEventHandlers = Exclude<
+ keyof EventHandlers,
+ typeof htmlElementAttributes['*'][keyof typeof htmlElementAttributes['*']]
+>;
+
+type input = Exclude<
+ keyof EventHandlers,
+ typeof htmlElementAttributes['*'][keyof typeof htmlElementAttributes['*']]
+>;
+
+const htmlElementAttributes = {
+ '*': [
+ 'onauxclick',
+ 'onbeforematch',
+ 'onblur',
+ 'oncancel',
+ 'oncanplay',
+ 'oncanplaythrough',
+ 'onchange',
+ 'onclick',
+ 'onclose',
+ 'oncontextlost',
+ 'oncontextmenu',
+ 'oncontextrestored',
+ 'oncopy',
+ 'oncuechange',
+ 'oncut',
+ 'ondblclick',
+ 'ondrag',
+ 'ondragend',
+ 'ondragenter',
+ 'ondragleave',
+ 'ondragover',
+ 'ondragstart',
+ 'ondrop',
+ 'ondurationchange',
+ 'onemptied',
+ 'onended',
+ 'onerror',
+ 'onfocus',
+ 'onformdata',
+ 'oninput',
+ 'oninvalid',
+ 'onkeydown',
+ 'onkeypress',
+ 'onkeyup',
+ 'onload',
+ 'onloadeddata',
+ 'onloadedmetadata',
+ 'onloadstart',
+ 'onmousedown',
+ 'onmouseenter',
+ 'onmouseleave',
+ 'onmousemove',
+ 'onmouseout',
+ 'onmouseover',
+ 'onmouseup',
+ 'onpaste',
+ 'onpause',
+ 'onplay',
+ 'onplaying',
+ 'onprogress',
+ 'onratechange',
+ 'onreset',
+ 'onresize',
+ 'onscroll',
+ 'onsecuritypolicyviolation',
+ 'onseeked',
+ 'onseeking',
+ 'onselect',
+ 'onslotchange',
+ 'onstalled',
+ 'onsubmit',
+ 'onsuspend',
+ 'ontimeupdate',
+ 'ontoggle',
+ 'onvolumechange',
+ 'onwaiting',
+ 'onwheel',
+ ],
+ a: [],
+ abbr: [],
+ address: [],
+ area: [],
+ article: [],
+ aside: [],
+ audio: [],
+ b: [],
+ base: [],
+ bdi: [],
+ bdo: [],
+ blockquote: [],
+ body: [],
+ br: [],
+ button: [],
+ canvas: [],
+ caption: [],
+ cite: [],
+ code: [],
+ col: [],
+ colgroup: [],
+ data: [],
+ datalist: [],
+ dd: [],
+ del: [],
+ details: [],
+ dfn: [],
+ dialog: [],
+ dir: [],
+ div: [],
+ dl: [],
+ dt: [],
+ em: [],
+ embed: [],
+ fieldset: [],
+ figcaption: [],
+ figure: [],
+ font: [],
+ footer: [],
+ form: [],
+ frame: [],
+ frameset: [],
+ h1: [],
+ h2: [],
+ h3: [],
+ h4: [],
+ h5: [],
+ h6: [],
+ head: [],
+ header: [],
+ hgroup: [],
+ hr: [],
+ html: [],
+ i: [],
+ iframe: [],
+ img: [],
+ input: [],
+ ins: [],
+ kbd: [],
+ label: [],
+ legend: [],
+ li: [],
+ link: [],
+ main: [],
+ map: [],
+ mark: [],
+ marquee: [],
+ menu: [],
+ meta: [],
+ meter: [],
+ nav: [],
+ noscript: [],
+ object: [],
+ ol: [],
+ optgroup: [],
+ option: [],
+ output: [],
+ p: [],
+ param: [],
+ picture: [],
+ pre: [],
+ progress: [],
+ q: [],
+ rp: [],
+ rt: [],
+ ruby: [],
+ s: [],
+ samp: [],
+ script: [],
+ section: [],
+ select: [],
+ slot: [],
+ small: [],
+ source: [],
+ span: [],
+ strong: [],
+ style: [],
+ sub: [],
+ summary: [],
+ sup: [],
+ table: [],
+ tbody: [],
+ td: [],
+ template: [],
+ textarea: [],
+ tfoot: [],
+ th: [],
+ thead: [],
+ time: [],
+ title: [],
+ tr: [],
+ track: [],
+ u: [],
+ ul: [],
+ var: [],
+ video: [],
+ wbr: [],
+} as const;
+
+export default htmlElementAttributes;
diff --git a/src/lib/_misc/html-elements-map.ts b/src/lib/_misc/html-elements-map.ts
new file mode 100644
index 0000000..8d9c8e9
--- /dev/null
+++ b/src/lib/_misc/html-elements-map.ts
@@ -0,0 +1,124 @@
+import { HTMLElementsMap } from '../types/_utils';
+
+const htmlElementsMap: HTMLElementsMap = {
+ '*': [],
+ a: [],
+ abbr: [],
+ address: [],
+ area: [],
+ article: [],
+ aside: [],
+ audio: [],
+ b: [],
+ base: [],
+ bdi: [],
+ bdo: [],
+ blockquote: [],
+ body: [],
+ br: [],
+ button: [],
+ canvas: [],
+ caption: [],
+ cite: [],
+ code: [],
+ col: [],
+ colgroup: [],
+ data: [],
+ datalist: [],
+ dd: [],
+ del: [],
+ details: [],
+ dfn: [],
+ dialog: [],
+ dir: [],
+ div: [],
+ dl: [],
+ dt: [],
+ em: [],
+ embed: [],
+ fieldset: [],
+ figcaption: [],
+ figure: [],
+ font: [],
+ footer: [],
+ form: [],
+ frame: [],
+ frameset: [],
+ h1: [],
+ h2: [],
+ h3: [],
+ h4: [],
+ h5: [],
+ h6: [],
+ head: [],
+ header: [],
+ hgroup: [],
+ hr: [],
+ html: [],
+ i: [],
+ iframe: [],
+ img: [],
+ input: [],
+ ins: [],
+ kbd: [],
+ label: [],
+ legend: [],
+ li: [],
+ link: [],
+ main: [],
+ map: [],
+ mark: [],
+ marquee: [],
+ menu: [],
+ meta: [],
+ meter: [],
+ nav: [],
+ noscript: [],
+ object: [],
+ ol: [],
+ optgroup: [],
+ option: [],
+ output: [],
+ p: [],
+ param: [],
+ picture: [],
+ pre: [],
+ progress: [],
+ q: [],
+ rp: [],
+ rt: [],
+ ruby: [],
+ s: [],
+ samp: [],
+ script: [],
+ section: [],
+ select: [],
+ slot: [],
+ small: [],
+ source: [],
+ span: [],
+ strong: [],
+ style: [],
+ sub: [],
+ summary: [],
+ sup: [],
+ table: [],
+ tbody: [],
+ td: [],
+ template: [],
+ textarea: [],
+ tfoot: [],
+ th: [],
+ thead: [],
+ time: [],
+ title: [],
+ tr: [],
+ track: [],
+ u: [],
+ ul: [],
+ var: [],
+ video: [],
+ wbr: [],
+} as const;
+
+export default htmlElementsMap;
diff --git a/src/lib/_misc/mutable-elements.ts b/src/lib/_misc/mutable-elements.ts
new file mode 100644
index 0000000..3b29211
--- /dev/null
+++ b/src/lib/_misc/mutable-elements.ts
@@ -0,0 +1,192 @@
+import propProcessors from '../propProcessors';
+import { FunctionProps, WritableProps } from './_utils';
+
+type Processors = ReturnType;
+type ProcessorTypes = {
+ [Key in keyof Processors]: Parameters[0];
+};
+
+type ExtractedHTMLProps = Pick<
+ E,
+ Exclude, FunctionProps | keyof Processors>
+> &
+ ProcessorTypes &
+ GlobalEventHandlers;
+
+type Element = ExtractedHTMLProps;
+type AnchorElement = ExtractedHTMLProps;
+type AreaElement = ExtractedHTMLProps;
+type AudioElement = ExtractedHTMLProps;
+type BaseElement = ExtractedHTMLProps;
+type QuoteElement = ExtractedHTMLProps;
+type BodyElement = ExtractedHTMLProps;
+type BRElement = ExtractedHTMLProps;
+type CanvasElement = ExtractedHTMLProps;
+type ButtonElement = ExtractedHTMLProps;
+type TableCaptionElement = ExtractedHTMLProps;
+type TableColElement = ExtractedHTMLProps;
+type DataElement = ExtractedHTMLProps;
+type DataListElement = ExtractedHTMLProps;
+type ModElement = ExtractedHTMLProps;
+type DetailsElement = ExtractedHTMLProps;
+type DivElement = ExtractedHTMLProps;
+type DListElement = ExtractedHTMLProps;
+type EmbedElement = ExtractedHTMLProps;
+type FieldSetElement = ExtractedHTMLProps;
+type FormElement = ExtractedHTMLProps;
+type HeadingElement = ExtractedHTMLProps;
+type HeadElement = ExtractedHTMLProps;
+type HRElement = ExtractedHTMLProps;
+type IFrameElement = ExtractedHTMLProps;
+type ImageElement = ExtractedHTMLProps;
+type InputElement = ExtractedHTMLProps;
+type LabelElement = ExtractedHTMLProps;
+type LegendElement = ExtractedHTMLProps;
+type ListItemElement = ExtractedHTMLProps;
+type LinkElement = ExtractedHTMLProps;
+type MapElement = ExtractedHTMLProps;
+type MenuElement = ExtractedHTMLProps;
+type MetaElement = ExtractedHTMLProps;
+type MeterElement = ExtractedHTMLProps;
+type ObjectElement = ExtractedHTMLProps;
+type OListElement = ExtractedHTMLProps;
+type OptGroupElement = ExtractedHTMLProps;
+type OptionElement = ExtractedHTMLProps;
+type OutputElement = ExtractedHTMLProps;
+type ParagraphElement = ExtractedHTMLProps;
+type ParamElement = ExtractedHTMLProps;
+type PictureElement = ExtractedHTMLProps;
+type PreElement = ExtractedHTMLProps;
+type ProgressElement = ExtractedHTMLProps;
+type ScriptElement = ExtractedHTMLProps;
+type SelectElement = ExtractedHTMLProps;
+type SlotElement = ExtractedHTMLProps;
+type SourceElement = ExtractedHTMLProps;
+type SpanElement = ExtractedHTMLProps;
+type StyleElement = ExtractedHTMLProps;
+type TableElement = ExtractedHTMLProps;
+type TableSectionElement = ExtractedHTMLProps;
+type TableCellElement = ExtractedHTMLProps;
+type TemplateElement = ExtractedHTMLProps;
+type TextAreaElement = ExtractedHTMLProps;
+type TimeElement = ExtractedHTMLProps;
+type TitleElement = ExtractedHTMLProps;
+type TableRowElement = ExtractedHTMLProps;
+type TrackElement = ExtractedHTMLProps;
+type UListElement = ExtractedHTMLProps;
+type VideoElement = ExtractedHTMLProps;
+
+type MutableElements = {
+ a: AnchorElement;
+ abbr: Element;
+ address: Element;
+ area: AreaElement;
+ article: Element;
+ aside: Element;
+ audio: AudioElement;
+ b: Element;
+ base: BaseElement;
+ bdi: Element;
+ bdo: Element;
+ blockquote: QuoteElement;
+ body: BodyElement;
+ br: BRElement;
+ button: ButtonElement;
+ canvas: CanvasElement;
+ caption: TableCaptionElement;
+ cite: Element;
+ code: Element;
+ col: TableColElement;
+ colgroup: TableColElement;
+ data: DataElement;
+ datalist: DataListElement;
+ dd: Element;
+ del: ModElement;
+ details: DetailsElement;
+ dfn: Element;
+ div: DivElement;
+ dl: DListElement;
+ dt: Element;
+ em: Element;
+ embed: EmbedElement;
+ fieldset: FieldSetElement;
+ figcaption: Element;
+ figure: Element;
+ footer: Element;
+ form: FormElement;
+ h1: HeadingElement;
+ h2: HeadingElement;
+ h3: HeadingElement;
+ h4: HeadingElement;
+ h5: HeadingElement;
+ h6: HeadingElement;
+ head: HeadElement;
+ header: Element;
+ hgroup: Element;
+ hr: HRElement;
+ i: Element;
+ iframe: IFrameElement;
+ img: ImageElement;
+ input: InputElement;
+ ins: ModElement;
+ kbd: Element;
+ label: LabelElement;
+ legend: LegendElement;
+ li: ListItemElement;
+ link: LinkElement;
+ main: Element;
+ map: MapElement;
+ mark: Element;
+ menu: MenuElement;
+ meta: MetaElement;
+ meter: MeterElement;
+ nav: Element;
+ noscript: Element;
+ object: ObjectElement;
+ ol: OListElement;
+ optgroup: OptGroupElement;
+ option: OptionElement;
+ output: OutputElement;
+ p: ParagraphElement;
+ param: ParamElement;
+ picture: PictureElement;
+ pre: PreElement;
+ progress: ProgressElement;
+ q: QuoteElement;
+ rp: Element;
+ rt: Element;
+ ruby: Element;
+ s: Element;
+ samp: Element;
+ script: ScriptElement;
+ section: Element;
+ select: SelectElement;
+ slot: SlotElement;
+ small: Element;
+ source: SourceElement;
+ span: SpanElement;
+ strong: Element;
+ style: StyleElement;
+ sub: Element;
+ summary: Element;
+ sup: Element;
+ table: TableElement;
+ tbody: TableSectionElement;
+ td: TableCellElement;
+ template: TemplateElement;
+ textarea: TextAreaElement;
+ tfoot: TableSectionElement;
+ th: TableCellElement;
+ thead: TableSectionElement;
+ time: TimeElement;
+ title: TitleElement;
+ tr: TableRowElement;
+ track: TrackElement;
+ u: Element;
+ ul: UListElement;
+ var: Element;
+ video: VideoElement;
+ wbr: Element;
+};
+
+export default MutableElements;
diff --git a/src/lib/_misc/props.ts b/src/lib/_misc/props.ts
new file mode 100644
index 0000000..4ead016
--- /dev/null
+++ b/src/lib/_misc/props.ts
@@ -0,0 +1,35 @@
+import { MaybeMutable } from '@mutablejs/core';
+import propProcessors from '../propProcessors';
+import { WritableProps } from './_utils';
+
+type Processors = ReturnType;
+type ProcessorTypes = {
+ [Key in keyof Processors]?: MaybeMutable[0]>;
+};
+
+type FunctionProps = {
+ [Prop in keyof HTMLElementTagNameMap[Tag]]: HTMLElementTagNameMap[Tag][Prop] extends Function
+ ? Prop
+ : never;
+}[keyof HTMLElementTagNameMap[Tag]];
+
+type EventProps = {
+ [K in keyof HTMLElementTagNameMap[Tag]]: K extends `on${infer A}`
+ ? keyof HTMLElementTagNameMap[Tag] & `on${A}`
+ : never;
+}[keyof HTMLElementTagNameMap[Tag]];
+
+type _WritableProps = Exclude<
+ WritableProps,
+ Exclude, EventProps>
+>;
+
+type HTMLElementProps = {
+ [Tag in keyof HTMLElementTagNameMap]: {
+ [Prop in _WritableProps]?: MaybeMutable<
+ HTMLElementTagNameMap[Tag][Prop]
+ >;
+ } & ProcessorTypes;
+};
+
+export default HTMLElementProps;
diff --git a/src/lib/_misc/tb-discarded.ts b/src/lib/_misc/tb-discarded.ts
new file mode 100644
index 0000000..2608ac1
--- /dev/null
+++ b/src/lib/_misc/tb-discarded.ts
@@ -0,0 +1,66 @@
+const ElementEventHandlers = {
+ '*': [
+ 'onabort',
+ 'onautocomplete',
+ 'onautocompleteerror',
+ 'onblur',
+ 'oncancel',
+ 'oncanplay',
+ 'oncanplaythrough',
+ 'onchange',
+ 'onclick',
+ 'onclose',
+ 'oncontextmenu',
+ 'oncuechange',
+ 'ondblclick',
+ 'ondrag',
+ 'ondragend',
+ 'ondragenter',
+ 'ondragleave',
+ 'ondragover',
+ 'ondragstart',
+ 'ondrop',
+ 'ondurationchange',
+ 'onemptied',
+ 'onended',
+ 'onerror',
+ 'onfocus',
+ 'oninput',
+ 'oninvalid',
+ 'onkeydown',
+ 'onkeypress',
+ 'onkeyup',
+ 'onload',
+ 'onloadeddata',
+ 'onloadedmetadata',
+ 'onloadstart',
+ 'onmousedown',
+ 'onmouseenter',
+ 'onmouseleave',
+ 'onmousemove',
+ 'onmouseout',
+ 'onmouseover',
+ 'onmouseup',
+ 'onmousewheel',
+ 'onpause',
+ 'onplay',
+ 'onplaying',
+ 'onprogress',
+ 'onratechange',
+ 'onreset',
+ 'onresize',
+ 'onscroll',
+ 'onseeked',
+ 'onseeking',
+ 'onselect',
+ 'onshow',
+ 'onsort',
+ 'onstalled',
+ 'onsubmit',
+ 'onsuspend',
+ 'ontimeupdate',
+ 'ontoggle',
+ 'onvolumechange',
+ 'onwaiting',
+ ],
+} as const;