diff --git a/README.md b/README.md
index b5e651a..31c6526 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,258 @@
# X10D
-Extension methods on crack
+## Extension methods on crack
-## About
-X10D (pronounced *extend*), is a collection of class libraries that provide various .NET extension methods, including extension methods for Unity, Windows Forms and System.Drawing.
+[](https://github.com/oliverbooth/X10D/actions?query=workflow%3A%22.NET+Core%22)
+[](https://github.com/oliverbooth/X10D/issues)
+[](https://www.nuget.org/packages/X10D/)
+[](https://github.com/oliverbooth/X10D/blob/master/LICENSE.md)
+
+### About
+X10D (pronounced *extend*), is a class library that provides extension methods for numerous .NET types. The purpose of this library is to simplify a codebase by reducing the need for repeated code when performing common operations. Simplify your codebase. Take advantage of .NET. Use extension methods.
+
+*(I'm also [dogfooding](https://deviq.com/dogfooding/) this library, so there's that.)*
+
+### Table of contents
+- [Install](#install)
+- [Features](#features)
+ - [Numeric](#numeric)
+ - [String](#string)
+ - [DateTime](#datetime)
+ - [Enumerable](#enumerable)
+ - [Enum](#enum)
+ - [Conversion](#conversion)
+ - [Random](#random)
+- [License](#license)
-## Extended Classes
You can find the list of classes that have extension methods by viewing the `README.md` file in any of the respective library folders.
+
+## Install
+Install X10D with NuGet via the following command:
+```ps
+Install-Package X10D -Version 2.0.0
+```
+or by downloading the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository.
+
+## Features
+### Numeric extensions
+> 👍 ProTip: *Most* of the extensions available for `int` will also exist for `short`, `long`, and their unsigned counterparts!
+
+#### `bool` <-> `int`
+Convert a `bool` to an `int` by using `ToInt32`. The value returned is 1 if the input is `true`, and 0 if it's `false`.
+```cs
+bool b = true;
+
+int i = b.ToInt32(); // 1
+```
+The same also works in reverse. Using `ToBoolean` on an `int` will return `false` if the input is 0, and `true`if the input is anything else.
+```cs
+int zero = 0;
+long nonZero = 1;
+
+bool b1 = zero.ToBoolean(); // false
+bool b2 = nonZero.ToBoolean(); // true
+```
+
+#### Between
+Determine if a value is between other values using `Between` like so:
+```cs
+int i = 3;
+
+if (i.Between(2, 4))
+{
+ // i is between 2 and 4!
+}
+```
+Since the signature of this method is defined with a generic constraint of `IComparable`, this will also work for any object that is `IComparable` - not just numeric types!
+```cs
+bool Between(this T actual, T lower, T upper) where T : IComparable
+```
+
+#### IsEven (*and IsOdd*)
+As the names suggest, this method determines if the input value is evenly divisible by 2.
+```cs
+int i = 5;
+bool b = i.IsEven(); // false
+```
+There is also an `IsOdd` extension method, which will return the opposite of that returned by `IsEven`.
+
+#### IsPrime
+Determine if an integral is a prime number by using `IsPrime`.
+```cs
+bool b = 43.IsPrime(); // true
+```
+
+#### Clamp
+Clamp a value between an upper and lower bound
+```cs
+int i = 5.Clamp(0, 3); // 3
+```
+
+#### Convert degrees <-> radians
+Easily convert between radians and degrees
+```cs
+double rad = 2 * Math.PI;
+double deg = rad.RadiansToDegrees(); // 360
+
+rad = deg.DegreesToRadians(); // back to 2*pi
+```
+
+#### Round
+Round a value to the nearest whole number:
+```cs
+var d = 2.75;
+var rounded = d.Round(); // 3
+```
+Or specify a value to have it round to the nearest multiple of `x`:
+```cs
+double a = 8.0.Round(10); // 10
+double b = 2.0.Round(10); // 0
+```
+
+### String
+#### Repeat value
+Repeat a string or a char a specific number of times using `Repeat`
+```cs
+var c = '-';
+var str = "foo";
+
+string repeatedC = c.Repeat(10); // ----------
+string repeatedStr = str.Repeat(5); // foofoofoofoofoo
+```
+
+#### Base-64 encode/decode
+```cs
+var base64 = "Hello World".Base64Encode(); // SGVsbG8gV29ybGQ=
+var str = "SGVsbG8gV29ybGQ=".Base64Decode(); // Hello World
+```
+
+### DateTime
+
+#### Age
+Get a rounded integer representing the number of years since a given date. i.e. easily calculate someone's age:
+```cs
+var dateOfBirth = new DateTime(1960, 7, 16);
+int age = dateOfBirth.Age(); // the age as of today
+```
+You can also specify a date at which to stop counting the years, by passing an `asOf` date:
+```cs
+var dateOfBirth = new DateTime(1960, 7, 16);
+int age = dateOfBirth.Age(new DateTime(1970, 7, 16)); // 10, the age as of 1970
+```
+
+#### To/From Unix Timestamp
+Convert to/from a Unix timestamp represented in seconds using `FromUnixTimestamp` on a numeric type, and `ToUnixTimestamp` on a `DateTime`.
+```cs
+long sec = 1587223415;
+DateTime time = sec.FromUnixTimestamp(); // 2020-04-18 15:23:35
+long unix = time.ToUnixTimestamp();
+```
+or represent it with milliseconds by passing `true` for the `isMillis` argument:
+```cs
+long millis = 1587223415500;
+DateTime time = millis.FromUnixTimestamp(true); // 2020-04-18 15:23:35.50
+long unix = time.ToUnixTimestamp(true);
+```
+
+#### Get first/last day of month
+Get the first or last day of the month by using `FirstDayOfMonth` and `LastDayOfMonth`
+```cs
+var dt = new DateTime(2016, 2, 4);
+
+DateTime first = dt.FirstDayOfMonth(); // 2016-02-01
+DateTime last = dt.LastDayOfMonth(); // 2016-02-29 (2016 is a leap year)
+```
+You can also use `First` or `Last` to get the first or final occurrence of a specific day of the week in a given month:
+```cs
+var dt = new DateTime(2019, 4, 14);
+
+DateTime theLastFriday = dt.Last(DayOfWeek.Friday); // 2019-04-24
+DateTime theLastThursday = dt.Last(DayOfWeek.Thursday); // 2019-04-40
+```
+
+### Enumerable
+#### Split into chunks
+Split an `IEnumerable` into an `IEnumerable>`, essentially "chunking" the original IEnumerable into a specific size
+```cs
+var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
+var chunks = arr.Split(2); // split into chunks of 2
+
+foreach (var chunk in chunks)
+{
+ Console.WriteLine(string.Join(", ", chunk));
+}
+
+// Output:
+// 1, 2
+// 3, 4
+// 5, 6
+// 7, 8
+```
+This also works for `string`:
+```cs
+var str = "Hello World";
+var chunks = str.Split(2); // split string into chunks of 2
+
+foreach (var chunk in chunks)
+{
+ Console.WriteLine(string.Join(string.Empty, chunk));
+}
+
+// Output:
+// He
+// ll
+// o <-- space is included
+// Wo
+// rl
+// d <-- no space! end of string
+```
+
+### Enum
+#### Parse string into enum
+You can use the `EnumParse` method to convert a string into a value from an enum, while optionally ignoring case:
+```cs
+enum Number
+{
+ Zero,
+ One,
+ Two,
+ Three,
+}
+
+Number num = "two".EnumParse(true); // num == Number.Two
+```
+
+#### `Next` / `Previous` enum cycling
+Cycle through the values in an enum with `Next` and `Previous`:
+```cs
+Number two = Number.Two;
+
+Number one = two.Previous();
+Number three = two.Next();
+```
+
+### Conversion
+Easily convert between types using `To`, `ToOrNull`, `ToOrDefault`, or `ToOrOther`, thereby shortening the call to `Convert.ChangeType` or `Convert.ToX`:
+```CS
+int i = "43".To();
+int j = "a".ToOrDefault(); // 0
+int k = "a".ToOrOther(100); // 100
+```
+
+### Random
+Do more with Random including flip a coin, randomly select an element in an array, or shuffle the array entirely.
+```cs
+var random = new Random();
+
+// flip a coin
+bool heads = random.CoinToss();
+
+// randomly choose an item
+var arr = new int[] { 1, 2, 3, 4 };
+var item = random.OneOf(arr);
+
+// shuffle an array or list
+var shuffled = arr.Shuffle(random);
+```
+
+## License
+X10D is released under the MIT License. See [here](https://github.com/oliverbooth/X10D/blob/master/LICENSE.md) for more details.
\ No newline at end of file