diff --git a/dub.sdl b/dub.sdl
index 06e4283..66590d2 100644
--- a/dub.sdl
+++ b/dub.sdl
@@ -5,8 +5,6 @@ copyright "Copyright © 2023, Inochi2D Project"
 license "BSD 2-clause"
 targetPath "out/"
 
-dependency "tinyd-rt" version=">=0.0.0" optional=true
-
 buildOptions "debugInfoC" platform="windows"
 
 configuration "main" {
diff --git a/source/numem/all.d b/source/numem/all.d
index c462a57..79726e9 100644
--- a/source/numem/all.d
+++ b/source/numem/all.d
@@ -6,16 +6,10 @@
 */
 
 /**
-    Automatically imports all of the numem types.
+    Automatically imports all of the base numem functionality.
+    Some extra functionality has to be 
 */
+deprecated("To import core numem functionality, just import numem.")
 module numem.all;
 
-public import numem.core;
-public import numem.core.memory;
-public import numem.collections;
-public import numem.core.exception;
-public import numem.io;
-public import numem.string;
-public import numem.conv;
-public import numem.events;
-public import numem.format;
+public import numem;
\ No newline at end of file
diff --git a/source/numem/collections/map.d b/source/numem/collections/map.d
index e500b53..d047d7b 100644
--- a/source/numem/collections/map.d
+++ b/source/numem/collections/map.d
@@ -258,7 +258,7 @@ unittest {
     // Associative array of ints that are
     // indexed by string keys.
     // The KeyType is string.
-    map!(string, int) aa = nogc_construct!(map!(string, int))(); 
+    map!(string, int) aa; 
     aa["hello"] = 3; // set value associated with key "hello" to 3
     int value = aa["hello"]; // lookup value from a key
     assert(value == 3);
diff --git a/source/numem/collections/set.d b/source/numem/collections/set.d
index ed52474..12a5531 100644
--- a/source/numem/collections/set.d
+++ b/source/numem/collections/set.d
@@ -162,7 +162,7 @@ unittest {
 
 @("set: insertion, deletion and testing")
 unittest {
-    set!(string) keywords = nogc_construct!(set!string)();
+    set!(string) keywords;
 
     assert(keywords.insert("public"));
     assert(keywords.insert("private"));
diff --git a/source/numem/collections/vector.d b/source/numem/collections/vector.d
index 414c737..1861e8e 100644
--- a/source/numem/collections/vector.d
+++ b/source/numem/collections/vector.d
@@ -687,8 +687,7 @@ alias weak_vector(T) = VectorImpl!(T, false);
 
 @("vector: Issue #2")
 unittest {
-    class A {
-    }
+    class A { }
     shared_ptr!A a = shared_new!A();
     vector!(shared_ptr!A) v;
     v ~= a; // Used to crash, see Issue #2
diff --git a/source/numem/conv.d b/source/numem/conv.d
index adb5128..7eae453 100644
--- a/source/numem/conv.d
+++ b/source/numem/conv.d
@@ -9,9 +9,15 @@
     Utilities for converting between some basic types
 */
 module numem.conv;
+import numem.string;
+import numem.format;
 import core.stdc.stdlib;
 import std.traits;
-import numem.all;
+
+
+//
+//      TODO: REIMPLEMENT ALL OF THIS IN PURE D.
+//
 
 @nogc:
 
diff --git a/source/numem/core/env.d b/source/numem/core/env.d
deleted file mode 100644
index c12fbc5..0000000
--- a/source/numem/core/env.d
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-    Copyright © 2024, Inochi2D Project
-    Distributed under the 2-Clause BSD License, see LICENSE file.
-
-    Authors: Luna the Foxgirl
-*/
-
-/**
-    Numem environment managment support
-*/
-module numem.core.env;
-import numem.string;
-import numem.text.unicode;
-import numem.core.memory;
-
-version(Windows) import core.sys.windows.winbase : GetEnvironmentVariableW, SetEnvironmentVariableW;
-else import core.sys.posix.stdlib : setenv, getenv;
-import core.sys.windows.raserror;
-
-@nogc:
-
-/**
-    Interface to system environment.
-*/
-struct Environment {
-@nogc:
-private:
-    static nstring get(const(char)* key) {
-        version(Windows) {
-            auto utf16k = key.fromStringz.toUTF16;
-
-            // Try getting the size of the env var.
-            // if this fails, the env var is probably empty.
-            uint bufSize = GetEnvironmentVariableW(utf16k.ptr, null, 0);
-            if (bufSize == 0)
-                return nstring.init;
-            
-            // Windows includes the null terminator, but n*string does too
-            // so to not have 2 null terminators, subtract 1.
-            nwstring envstr = nwstring(bufSize-1);
-            bufSize = GetEnvironmentVariableW(utf16k.ptr, cast(wchar*)envstr.ptr, cast(uint)(envstr.length+1));
-
-            nogc_delete(utf16k);
-            return envstr.toUTF8;
-        } else {
-            return nstring(getenv(key));
-        }
-    }
-
-    static bool set(const(char)* key, nstring value) {
-        version(Windows) {
-            auto utf16k = key.fromStringz.toUTF16();
-            auto utf16v = value.toUTF16();
-            return cast(bool)SetEnvironmentVariableW(utf16k.ptr, utf16v.ptr);
-        } else {
-            return setenv(key, value.ptr, 1) == 0;
-        }
-    }
-
-public:
-
-    /**
-        Returns the value at the given key.
-
-        Returns an empty nstring if key was not found.
-    */
-    static ref auto opIndex(const(char)* key) {
-        return get(key);
-    }
-
-    /**
-        Sets the value at the given key.
-    */
-    static void opIndexAssign(string value, const(char)* key) {
-        set(key, nstring(value));
-    }
-
-    /**
-        Appends to the value at the given key.
-    */
-    static void opIndexOpAssign(string op = "~")(string value, const(char)* key) {
-        auto tmp = get(key);
-        tmp ~= value;
-        set(key, tmp);
-    }
-}
-
-@("Environment: Get and Set")
-unittest {
-    auto envA = Environment["A"];
-    assert(envA.empty());
-
-    Environment["A"] = "Hello, world!";
-    envA = Environment["A"];
-    assert(envA == "Hello, world!");
-}
\ No newline at end of file
diff --git a/source/numem/core/hooks.d b/source/numem/core/hooks.d
new file mode 100644
index 0000000..3c5aaef
--- /dev/null
+++ b/source/numem/core/hooks.d
@@ -0,0 +1,129 @@
+/*
+    Copyright © 2023, Inochi2D Project
+    Distributed under the 2-Clause BSD License, see LICENSE file.
+    
+    Authors: Luna Nielsen
+*/
+
+/**
+    Numem Hooks.
+
+    This file contains all the core hooks numem calls internally to handle memory.
+    Given that some platforms may not have a C standard library, these hooks allow you
+    to override how numem handles memory for such platforms from an external library.
+
+    In this case, all of the hooks presented here will need to be implemented to cover
+    all of the used internal hooks within numem.
+
+    Various extra hooks are provided in other files throughout numem, but are optional.
+*/
+module numem.core.hooks;
+public import core.attribute : weak;
+
+@nogc nothrow:
+
+/**
+    Allocates `bytes` worth of memory.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib alloc.
+*/
+@weak
+extern(C)
+void* nuAlloc(size_t bytes) {
+    import core.stdc.stdlib : malloc;
+    return malloc(bytes);
+}
+
+
+/**
+    Reallocates memory at `data` to be `bytes` worth of memory.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib realloc.
+*/
+@weak
+extern(C)
+void* nuRealloc(void* data, size_t newSize) {
+    import core.stdc.stdlib : realloc;
+    return realloc(data, newSize);
+}
+
+/**
+    Frees the memory at `data`.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib alloc.
+*/
+@weak
+extern(C)
+void nuFree(void* data) {
+    import core.stdc.stdlib : free;
+    free(data);
+}
+
+/**
+    Copies `bytes` worth of data from `src` into `dst`.
+    Memory needs to be allocated and within range.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib memcpy.
+*/
+@weak
+extern(C)
+void* nuMemcpy(inout(void)* dst, inout(void)* src, size_t bytes) {
+    import core.stdc.string : memcpy;
+    return memcpy(cast(void*)dst, cast(void*)src, bytes);
+}
+
+/**
+    Moves `bytes` worth of data from `src` into `dst`.
+    Memory needs to be allocated and within range.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib memmove.
+*/
+@weak
+extern(C)
+void* nuMemmove(void* dst, void* src, size_t bytes) {
+    import core.stdc.string : memmove;
+    return memmove(dst, src, bytes);
+}
+
+/**
+    Fills `dst` with `value` for `bytes` bytes.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib memset.
+*/
+void* nuMemset(void* dst, ubyte value, size_t bytes) {
+    import core.stdc.string : memset;
+    return memset(dst, value, bytes);
+}
+
+/**
+    Hook which forcefully quits or crashes the application due to an invalid state.
+    
+    NOTE: External libraries may override this
+    implementation.
+    
+    By default calls C stdlib abort.
+*/
+@weak
+extern(C)
+void nuAbort() {
+    import core.stdc.stdlib : abort;
+    abort();
+}
\ No newline at end of file
diff --git a/source/numem/core/memory/alloc.d b/source/numem/core/memory/alloc.d
deleted file mode 100644
index 4c099f1..0000000
--- a/source/numem/core/memory/alloc.d
+++ /dev/null
@@ -1,73 +0,0 @@
-module numem.core.memory.alloc;
-public import core.stdc.stdlib : free, malloc, exit;
-import std.traits;
-
-@nogc nothrow:
-
-// Deletion function signature.
-private extern (D) alias fp_t = void function (Object);
-
-/**
-    Destroy element with a destructor.
-*/
-@trusted
-void destruct(T, bool doFree=true)(ref T obj_) {
-
-    static if (isPointer!T || is(T == class)) {
-        if (obj_ !is null) {
-            auto cInfo = cast(ClassInfo)typeid(obj_);
-            if (cInfo) {
-                auto c = cInfo;
-
-                // Call destructors in order of most specific
-                // to least-specific
-                do {
-                    if (c.destructor)
-                        (cast(fp_t)c.destructor)(cast(Object)obj_);
-                } while((c = c.base) !is null);
-                
-            } else {
-
-                // Item is a struct, we can destruct it directly.
-                static if (__traits(hasMember, T, "__dtor")) {
-                    assumeNothrowNoGC!(typeof(&obj_.__dtor))(&obj_.__dtor)();
-                } else static if (__traits(hasMember, T, "__xdtor")) {
-                    assumeNothrowNoGC!(typeof(&obj_.__xdtor))(&obj_.__xdtor)();
-                }
-            }
-
-            static if (doFree) {
-                free(cast(void*)obj_);
-                obj_ = null;
-            }
-        }
-    } else {
-
-        // Item is a struct, we can destruct it.
-        static if (__traits(hasMember, T, "__dtor")) {
-            assumeNothrowNoGC!(typeof(&obj_.__dtor))(&obj_.__dtor)();
-        } else static if (__traits(hasMember, T, "__xdtor")) {
-            assumeNothrowNoGC!(typeof(&obj_.__xdtor))(&obj_.__xdtor)();
-        }
-    }
-}
-
-/**
-    Forces a function to assume that it's nogc compatible.
-*/
-auto assumeNoGC(T) (T t) {
-    static if (isFunctionPointer!T || isDelegate!T) {
-        enum attrs = functionAttributes!T | FunctionAttribute.nogc;
-        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
-    } else static assert(false);
-}
-
-/**
-    Forces a function to assume that it's nothrow nogc compatible.
-*/
-auto assumeNothrowNoGC(T) (T t) {
-    static if (isFunctionPointer!T || isDelegate!T) {
-        enum attrs = functionAttributes!T | FunctionAttribute.nogc | FunctionAttribute.nothrow_;
-        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
-    } else static assert(false);
-}
\ No newline at end of file
diff --git a/source/numem/core/memory/lifetime.d b/source/numem/core/memory/lifetime.d
new file mode 100644
index 0000000..1543d47
--- /dev/null
+++ b/source/numem/core/memory/lifetime.d
@@ -0,0 +1,233 @@
+/*
+    Copyright © 2023, Inochi2D Project
+    Distributed under the 2-Clause BSD License, see LICENSE file.
+    
+    Authors: Luna Nielsen
+*/
+
+/**
+    Lifetime handling in numem.
+*/
+module numem.core.memory.lifetime;
+import numem.core.utils;
+import numem.core.hooks;
+import numem.core.trace;
+import std.traits;
+import core.lifetime : forward;
+import core.internal.traits : isInnerClass;
+
+// Deletion function signature.
+private extern (D) alias fp_t = void function (Object) @nogc nothrow;
+
+/**
+    Destroy element with a destructor.
+*/
+@trusted
+void destruct(T, bool doFree=true)(ref T obj_) @nogc nothrow {
+
+    static if (isPointer!T || is(T == class)) {
+        if (obj_ !is null) {
+            auto cInfo = cast(ClassInfo)typeid(obj_);
+            if (cInfo) {
+                auto c = cInfo;
+
+                // Call destructors in order of most specific
+                // to least-specific
+                do {
+                    if (c.destructor)
+                        (cast(fp_t)c.destructor)(cast(Object)obj_);
+                } while((c = c.base) !is null);
+                
+            } else {
+
+                // Item is a struct, we can destruct it directly.
+                static if (__traits(hasMember, T, "__dtor")) {
+                    assumeNothrowNoGC!(typeof(&obj_.__dtor))(&obj_.__dtor)();
+                } else static if (__traits(hasMember, T, "__xdtor")) {
+                    assumeNothrowNoGC!(typeof(&obj_.__xdtor))(&obj_.__xdtor)();
+                }
+            }
+
+            static if (doFree) {
+                nuFree(cast(void*)obj_);
+                obj_ = null;
+            }
+        }
+    } else {
+
+        // Item is a struct, we can destruct it.
+        static if (__traits(hasMember, T, "__dtor")) {
+            assumeNothrowNoGC!(typeof(&obj_.__dtor))(&obj_.__dtor)();
+        } else static if (__traits(hasMember, T, "__xdtor")) {
+            assumeNothrowNoGC!(typeof(&obj_.__xdtor))(&obj_.__xdtor)();
+        }
+    }
+}
+
+/**
+    Runs copy postblit operations for `dst`.
+
+    If `dst` has a copy constructor it will be run,
+    otherwise if it has a `this(this)` postblit that will be run.
+
+    If no form of postblit is available, this function will be NO-OP.
+*/
+pragma(inline, true)
+void postblit(T)(ref T dst, ref T src) @nogc nothrow {
+    static if (__traits(hasCopyConstructor, T)) {
+        dst.__ctor(src);
+    } else static if(__traits(hasPostblit, T)) {
+        dst.__xpostblit();
+    }
+}
+
+/**
+    Runs move postblit operation for `dst`.
+*/
+pragma(inline, true)
+void move_postblit(T)(ref T dst, ref T src) @nogc nothrow {
+    static if (hasElaborateMove!T)
+        assumeNothrowNoGC!(typeof(&__move_post_blt))(&__move_post_blt)(dst, src);
+}
+
+/**
+    Gets the amount of bytes needed to allocate an instance of type `T`.
+*/
+template nuAllocSize(T) {
+    static if (is(T == class))
+        enum nuAllocSize = __traits(classInstanceSize, T);
+    else 
+        enum nuAllocSize = T.sizeof;
+}
+
+/**
+    Initializes the memory at the specified chunk.
+*/
+void initializeAt(T)(scope ref T chunk) @nogc nothrow @trusted {
+    static if (is(T == class)) {
+
+        // NOTE: class counts as a pointer, so its normal init symbol
+        // in general circumstances is null, we don't want this, so class check
+        // should be first! Otherwise the chunk = T.init will mess us up.
+        const void[] initSym = __traits(initSymbol, T);
+        nuMemcpy(cast(void*)chunk, initSym.ptr, initSym.length);
+    } else static if (__traits(isZeroInit, T)) {
+        nuMemset(cast(void*)&chunk, 0, T.sizeof);
+    } else static if (__traits(isScalar, T) || 
+        (T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, () { T chunk; chunk = T.init; }))) {
+        chunk = T.init;
+    } else static if (__traits(isStaticArray, T)) {
+        foreach(i; 0..T.length)
+            initializeAt(chunk[i]);
+    } else {
+        const void[] initSym = __traits(initSymbol, T);
+        nuMemcpy(cast(void*)&chunk, initSym.ptr, initSym.length);
+    }
+}
+
+/**
+    Runs constructor for the memory at dst
+*/
+void emplace(T, UT, Args...)(ref UT dst, auto ref Args args) @nogc nothrow {
+    enum isConstructibleOther =
+        (!is(T == struct) && Args.length == 1) ||                        // Primitives, enums, arrays.
+        (Args.length == 1 && is(typeof({T t = forward!(args[0]); }))) || // Conversions
+        is(typeof(T(forward!args)));                                     // General constructors.
+
+    static if (is(T == class)) {
+
+        static assert(!__traits(isAbstractClass, T), 
+            T.stringof ~ " is abstract and can't be emplaced.");
+
+        // NOTE: Since we need to handle inner-classes
+        // we need to initialize here instead of next to the ctor.
+        initializeAt(dst);
+        
+        static if (isInnerClass!T) {
+            static assert(Args.length > 0,
+                "Initializing an inner class requires a pointer to the outer class");
+            
+            static assert(is(Args[0] : typeof(T.outer)),
+                "The first argument must be a pointer to the outer class");
+            
+            chunk.outer = args[0];
+            alias fargs = args[1..$];
+            alias fargsT = Args[1..$];
+
+        } else {
+            alias fargs = args;
+            alias fargsT = Args;
+        }
+        import core.stdc.stdio : printf;
+
+        static if (is(typeof(dst.__ctor(forward!fargs)))) {
+            assumeNothrowNoGC((T chunk, fargsT args) {
+                chunk.__ctor(forward!args);
+            })(dst, fargs);
+        } else {
+            static assert(fargs.length == 0 && !is(typeof(&T.__ctor)),
+                "No constructor for " ~ T.stringof ~ " found matching arguments "~fargsT.stringof~"!");
+        }
+
+    } else static if (args.length == 0) {
+
+        static assert(is(typeof({static T i;})),
+            "Cannot emplace a " ~ T.stringof ~ ", its constructor is marked with @disable.");
+        initializeAt(dst);
+    } else static if (isConstructibleOther) {
+
+        // Handler struct which forwards construction
+        // to the payload.
+        static struct S {
+            T payload;
+            this()(auto ref Args args) {
+                static if (__traits(compiles, payload = forward!args))
+                    payload = forward!args;
+                else
+                    payload = T(forward!args);
+            }
+        }
+
+        if (__ctfe) {
+            static if (__traits(compiles, dst = T(forward!args)))
+                dst = T(forward!args);
+            else static if(args.length == 1 && __traits(compiles, dst = forward!(args[0])))
+                dst = forward!(args[0]);
+            else static assert(0,
+                "Can't emplace " ~ T.stringof ~ " at compile-time using " ~ Args.stringof ~ ".");
+        } else {
+            S* p = cast(S*)cast(void*)&dst;
+            static if (UT.sizeof > 0)
+                initializeAt(*p);
+            
+            p.__ctor(forward!args);
+        }
+    } else static if (is(typeof(dst.__ctor(forward!args)))) {
+        
+        initializeAt(dst);
+        assumeNothrowNoGC((T chunk, Args args) {
+            chunk.__ctor(forward!args);
+        })(dst, args);
+    } else {
+        static assert(!(Args.length == 1 && is(Args[0] : T)),
+            "Can't emplace a " ~ T.stringof ~ " because the postblit is disabled.");
+
+        static assert(0, 
+            "No constructor for " ~ T.stringof ~ " found matching arguments "~fargs.stringof~"!");
+    }
+}
+
+/// 
+void emplace(UT, Args...)(auto ref UT dst, auto ref Args args) @nogc nothrow {
+    emplace!(UT, UT, Args)(dst, forward!args);
+}
+
+/**
+    Gets the reference type version of type T.
+*/
+template RefT(T) {
+    static if (is(T == class) || isPointer!T)
+        alias RefT = T;
+    else
+        alias RefT = T*;
+}
\ No newline at end of file
diff --git a/source/numem/core/memory/package.d b/source/numem/core/memory/package.d
index 4a25c85..81f8c53 100644
--- a/source/numem/core/memory/package.d
+++ b/source/numem/core/memory/package.d
@@ -6,95 +6,12 @@
 */
 
 module numem.core.memory;
-import numem.core.memory.alloc;
-import numem.core.trace;
+import numem.core.memory.lifetime;
+import numem.core.hooks;
 import std.traits;
-import core.stdc.string : memset;
 
 public import numem.core.memory.smartptr;
-
-version(Have_tinyd_rt) {
-    private __gshared
-    auto __gc_new(T, Args...)(Args args) {
-        return new T(args);
-    }
-} else {
-    import core.lifetime : copyEmplace, emplace;
-}
-
-private {
-    // NOTE: D's implementation of emplace makes it ambiguous what emplace to call in certain instances
-    // These functions forward to the correct D core functions for emplacing.
-
-    // Case: Is a class
-    T __impl_nogc_emplace(T, Args...)(void[] chunk, Args args) if(is(T == class)) {
-        return emplace!(T, Args)(chunk, args);
-    }
-
-    // Case: Is struct or basic pointer.
-    T* __impl_nogc_emplace(T, Args...)(T* chunk, Args args) if(!is(T == class)) {
-        return emplace!(T, Args)(chunk, args);
-    }
-
-    enum isAggregateStackType(T) = 
-        is(T == struct) || is(T == union);
-}
-
-nothrow @nogc:
-
-//
-//          MANUAL MEMORY MANAGMENT
-//
-private {
-
-    version(minimal_rt) {
-
-        // The type of the destructor caller
-        alias _impl_mrt_dfunctype = nothrow @nogc @system void function(void*);
-
-        // Generic destructor call
-        void _impl_destructorCall(T)(void* instance) nothrow @nogc {
-            import std.traits : BaseTypeTuple;
-
-            // Scope for base class destructor
-            static foreach(item; BaseClassesTuple!T) {
-                {
-                    static if (!is(item == Object) && !is(item == T)) {
-                        static if (__traits(hasMember, item, "__xdtor")) {
-                            auto dtorptr = &item.init.__xdtor;
-                            dtorptr.ptr = instance;
-                            dtorptr();
-                        } else static if (__traits(hasMember, item, "__dtor")) {
-                            auto dtorptr = &item.init.__dtor;
-                            dtorptr.ptr = instance;
-                            dtorptr();
-                        }
-                    }
-                }
-            }
-
-            // Scope for self destructor
-            {
-                static if (__traits(hasMember, T, "__xdtor")) {
-                    auto dtorptr = &T.init.__xdtor;
-                    dtorptr.ptr = instance;
-                    dtorptr();
-                } else static if (__traits(hasMember, T, "__dtor")) {
-                    auto dtorptr = &T.init.__dtor;
-                    dtorptr.ptr = instance;
-                    dtorptr();
-                }
-            }
-        }
-
-        // Structure for storing the destructor reference.
-        struct _impl_destructorStruct {
-            _impl_mrt_dfunctype destruct;
-        }
-    }
-}
-
-extern(C):
+debug(trace) import numem.core.trace;
 
 /**
     UDA which allows initializing an empty struct, even when copying is disabled.
@@ -102,106 +19,24 @@ extern(C):
 struct AllowInitEmpty;
 
 /**
-    Constructs a type, this allows initializing types on the stack instead of heap.
-*/
-T nogc_construct(T, Args...)(Args args) if (is(T == struct) || is(T == class) || is (T == union)) {
-    static if (is(T == class)) {
-        return (assumeNothrowNoGC(&__gc_new!(T, Args)))(args);
-    } else {
-        static if (hasUDA!(T, AllowInitEmpty) && args.length == 0) {
-            return T.init;
-        } else {
-            return T(args);
-        }
-    }
-}
-
-/**
-    Allocates a new struct on the heap.
-    Immediately exits the application if out of memory.
-*/
-T* nogc_new(T, Args...)(Args args) if (is(T == struct) || is(T == union)) {
-
-    version(Have_tinyd_rt) {
-        return (assumeNothrowNoGC(&__gc_new!(T, Args)))(args);
-    } else {
-        void* rawMemory = malloc(T.sizeof);
-        if (!rawMemory) {
-            exit(-1);
-        }
-
-        T* obj = cast(T*)rawMemory;
-        static if (hasUDA!(T, AllowInitEmpty) && args.length == 0) {
-            nogc_emplace!T(obj);
-        } static if (args.length == 1 && is(typeof(args[0]) == T)) {
-            nogc_copyemplace(obj, args[0]);
-        } else {
-            nogc_emplace!T(obj, args);
-        }
-
-        // Tracing
-        debug(trace) dbg_alloc(obj);
-
-        return obj;
-    }
-}
-
-/**
-    Allocates a new class on the heap.
-    Immediately exits the application if out of memory.
+    Allocates a new instance of type T.
 */
-T nogc_new(T, Args...)(Args args) if (is(T == class)) {
-
-    alias emplaceFunc = typeof(&emplace!T);
-
-    version(Have_tinyd_rt) {
-        return (assumeNothrowNoGC(&__gc_new!(T, Args)))(args);
-    } else version(minimal_rt) {
-        immutable(size_t) destructorObjSize = _impl_destructorStruct.sizeof;
-        immutable(size_t) classObjSize = __traits(classInstanceSize, T);
-        immutable size_t allocSize = classObjSize + destructorObjSize;
-
-        void* rawMemory = malloc(allocSize);
-        if (!rawMemory) {
-            exit(-1);
-        }
-
-        // Allocate class destructor list
-        nogc_emplace!classDestructorList(rawMemory[0..destructorObjSize], &_impl_destructorCall!T);
-
-        // Allocate class
-        T obj = nogc_emplace!T(rawMemory[destructorObjSize .. allocSize], args);
-
-        // Tracing
-        debug(trace) dbg_alloc(obj);
-        
-        return obj;
-    } else {
-        immutable size_t allocSize = __traits(classInstanceSize, T);
-        void* rawMemory = malloc(allocSize);
-        if (!rawMemory) {
-            exit(-1);
-        }
-
-        return nogc_emplace!T(rawMemory[0 .. allocSize], args);
-    }
-}
-
-/**
-    Allocates a new basic type on the heap.
-    Immediately exits the application if out of memory.
-*/
-T* nogc_new(T)(T value = T.init) if (isBasicType!T) {
-    T* rawMemory = cast(T*)malloc(T.sizeof);
-    if (!rawMemory) {
-        exit(-1);
-    }
+RefT!T nogc_new(T, Args...)(Args args) {
+    RefT!T newobject = cast(RefT!T)nuAlloc(nuAllocSize!T);
+    if (!newobject)
+        nuAbort();
+
+    static if (is(T == class) || isPointer!T)
+        emplace(newobject, args);
+    else
+        emplace(*newobject, args);
+    
 
     // Tracing
-    debug(trace) dbg_alloc(rawMemory);
-
-    *rawMemory = value;
-    return rawMemory;
+    debug(trace)
+        dbg_alloc(newobject);
+    
+    return newobject;
 }
 
 /**
@@ -210,18 +45,27 @@ T* nogc_new(T)(T value = T.init) if (isBasicType!T) {
     For structs this will call the struct's destructor if it has any.
 */
 void nogc_delete(T, bool doFree=true)(ref T obj_)  {
-
-    // Tracing
-    debug(trace) dbg_dealloc(obj_);
     
     destruct!(T, doFree)(obj_);
+
+    // Tracing
+    debug(trace)
+        dbg_dealloc(obj_);
+}
+
+/**
+    Initializes the object at `element`, filling it out with
+    its default state.
+*/
+void nogc_initialize(T)(ref T element) {
+    initializeAt(element);
 }
 
 /**
     Zero-fills an object
 */
 void nogc_zeroinit(T)(ref T element) {
-    memset(&element, 0, element.sizeof);
+    nuMemset(&element, 0, element.sizeof);
 }
 
 /**
@@ -229,27 +73,14 @@ void nogc_zeroinit(T)(ref T element) {
 */
 T nogc_zeroinit(T)() {
     T element;
-    memset(&element, 0, element.sizeof);
+    nuMemset(&element, 0, element.sizeof);
     return element;
 }
 
-auto nogc_copyemplace(T)(T* target, ref T source) {
-    alias t = typeof(&copyEmplace!(T, T));
-    return assumeNothrowNoGC!t(&copyEmplace!(T, T))(source, *target);
-}
-
 /**
-    nogc emplace function
-*/
-auto nogc_emplace(T, Args...)(T* chunk, Args args) {
-    alias t = typeof(&__impl_nogc_emplace!(T, Args));
-    return assumeNothrowNoGC!t(&__impl_nogc_emplace!(T, Args))(chunk, args);
-}
-
-/**
-    nogc emplace function
+    Allocates a new class on the heap.
+    Immediately exits the application if out of memory.
 */
-auto nogc_emplace(T, Args...)(void[] chunk, Args args) if (is(T == class)) {
-    alias t = typeof(&__impl_nogc_emplace!(T, Args));
-    return assumeNothrowNoGC!t(&__impl_nogc_emplace!(T, Args))(chunk, args);
+void nogc_emplace(T, Args...)(ref auto T dest, Args args)  {
+    emplace!(T, T, Args)(dest, args);
 }
\ No newline at end of file
diff --git a/source/numem/core/package.d b/source/numem/core/package.d
index 7d6798d..510c6a0 100644
--- a/source/numem/core/package.d
+++ b/source/numem/core/package.d
@@ -1,3 +1,4 @@
 module numem.core;
 
-public import numem.core.memory;
\ No newline at end of file
+public import numem.core.memory;
+public import numem.core.exception;
\ No newline at end of file
diff --git a/source/numem/core/utils.d b/source/numem/core/utils.d
new file mode 100644
index 0000000..d2dd6ee
--- /dev/null
+++ b/source/numem/core/utils.d
@@ -0,0 +1,34 @@
+/*
+    Copyright © 2023, Inochi2D Project
+    Distributed under the 2-Clause BSD License, see LICENSE file.
+    
+    Authors: Luna Nielsen
+*/
+
+/**
+    Utility functions which are used to break the D type system.
+
+    These should only be used when absolutely neccesary.
+*/
+module numem.core.utils;
+import std.traits;
+
+/**
+    Forces a function to assume that it's nogc compatible.
+*/
+auto assumeNoGC(T) (T t) {
+    static if (isFunctionPointer!T || isDelegate!T) {
+        enum attrs = functionAttributes!T | FunctionAttribute.nogc;
+        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
+    } else static assert(false);
+}
+
+/**
+    Forces a function to assume that it's nothrow nogc compatible.
+*/
+auto assumeNothrowNoGC(T) (T t) {
+    static if (isFunctionPointer!T || isDelegate!T) {
+        enum attrs = functionAttributes!T | FunctionAttribute.nogc | FunctionAttribute.nothrow_;
+        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
+    } else static assert(false);
+}
\ No newline at end of file
diff --git a/source/numem/env.d b/source/numem/env.d
new file mode 100644
index 0000000..6a018dd
--- /dev/null
+++ b/source/numem/env.d
@@ -0,0 +1,113 @@
+/*
+    Copyright © 2024, Inochi2D Project
+    Distributed under the 2-Clause BSD License, see LICENSE file.
+
+    Authors: Luna the Foxgirl
+*/
+
+/**
+    Numem Environment handling
+*/
+module numem.env;
+import numem.string;
+import numem.text.unicode;
+import numem.core.memory;
+import numem.core.hooks;
+
+@nogc:
+
+/**
+    Interface to system environment.
+*/
+struct Environment {
+@nogc:
+public:
+
+    /**
+        Returns the value at the given key.
+
+        Returns an empty nstring if key was not found.
+    */
+    static ref auto opIndex(const(char)* key) {
+        return nuGetEnvironmentVariable(nstring(key));
+    }
+
+    /**
+        Sets the value at the given key.
+    */
+    static bool opIndexAssign(string value, const(char)* key) {
+        return nuSetEnvironmentVariable(nstring(key), nstring(value));
+    }
+
+    /**
+        Appends to the value at the given key.
+    */
+    static bool opIndexOpAssign(string op = "~")(string value, const(char)* key) {
+        auto tmp = get(key);
+        tmp ~= value;
+        return nuSetEnvironmentVariable(nstring(key), tmp);
+    }
+}
+
+@("Environment: Get and Set")
+unittest {
+    auto envA = Environment["A"];
+    assert(envA.empty());
+
+    assert(Environment["A"] = "Hello, world!"); // We return whether setting succeeded.
+    envA = Environment["A"];
+    assert(envA == "Hello, world!");
+}
+
+/**
+    Hook which fetches the specified environment variable.
+*/
+@weak
+extern(C)
+nstring nuGetEnvironmentVariable(nstring key) @nogc {
+    version(Windows) {
+        import core.sys.windows.winbase : GetEnvironmentVariableW;
+        auto utf16k = key.toUTF16;
+
+        // Try getting the size of the env var.
+        // if this fails, the env var is probably empty.
+        uint bufSize = GetEnvironmentVariableW(utf16k.ptr, null, 0);
+        if (bufSize == 0)
+            return nstring.init;
+        
+        // Windows includes the null terminator, but n*string does too
+        // so to not have 2 null terminators, subtract 1.
+        nwstring envstr = nwstring(bufSize-1);
+        bufSize = GetEnvironmentVariableW(utf16k.ptr, envstr.ptr, envstr.length+1);
+
+        nogc_delete(utf16k);
+        return envstr.toUTF8;
+    } else version(Posix) {
+
+        import core.sys.posix.stdlib : getenv;
+        return nstring(getenv(key.ptr));
+    } else {
+        return nstring(null);
+    }
+}
+
+/**
+    Hook which sets the specified environment variable.
+*/
+@weak
+extern(C)
+bool nuSetEnvironmentVariable(nstring key, nstring val) @nogc {
+    version(Windows) {
+
+        import core.sys.windows.winbase : SetEnvironmentVariableW;
+        auto utf16k = key.toUTF16();
+        auto utf16v = value.toUTF16();
+        return SetEnvironmentVariableW(utf16k.ptr, utf16v.ptr);
+    } else version(Posix) {
+
+        import core.sys.posix.stdlib : setenv;
+        return setenv(key.ptr, val.ptr, 1) == 0;
+    } else {
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/source/numem/mem.d b/source/numem/mem.d
deleted file mode 100644
index c79df8b..0000000
--- a/source/numem/mem.d
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
-    Copyright © 2024, Inochi2D Project
-    Distributed under the 2-Clause BSD License, see LICENSE file.
-
-    Authors: Luna the Foxgirl
-*/
-
-deprecated("This module has been moved to numem.core")
-module numem.mem;
-
-public import numem.core;
\ No newline at end of file
diff --git a/source/numem/package.d b/source/numem/package.d
new file mode 100644
index 0000000..d4c15a2
--- /dev/null
+++ b/source/numem/package.d
@@ -0,0 +1,21 @@
+/*
+    Copyright © 2024, Inochi2D Project
+    Distributed under the 2-Clause BSD License, see LICENSE file.
+
+    Authors: Luna the Foxgirl
+*/
+
+/**
+    Automatically imports all of the base numem functionality.
+    Some extra functionality has to be 
+*/
+module numem;
+
+
+public import numem.core;
+public import numem.collections;
+public import numem.io;
+public import numem.string;
+public import numem.conv;
+public import numem.events;
+public import numem.format;
diff --git a/source/numem/core/random.d b/source/numem/random.d
similarity index 99%
rename from source/numem/core/random.d
rename to source/numem/random.d
index 0e3d586..72e639b 100644
--- a/source/numem/core/random.d
+++ b/source/numem/random.d
@@ -1,4 +1,4 @@
-module numem.core.random;
+module numem.random;
 import numem.core;
 import std.traits;
 
diff --git a/source/numem/core/uuid.d b/source/numem/uuid.d
similarity index 99%
rename from source/numem/core/uuid.d
rename to source/numem/uuid.d
index ce9e189..3b5099d 100644
--- a/source/numem/core/uuid.d
+++ b/source/numem/uuid.d
@@ -8,8 +8,8 @@
 /**
     RFC4122 compliant UUIDs
 */
-module numem.core.uuid;
-import numem.core.random;
+module numem.uuid;
+import numem.random;
 import numem.string;
 import numem.io.endian;
 import numem.conv;