diff --git a/src/articles/check-back-later.md b/src/articles/check-back-later.md
deleted file mode 100644
index 7d62324..0000000
--- a/src/articles/check-back-later.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: Check Back Later
-description: I don't have any articles yet, but check back later!
-slug: check-back-later
-authors:
-  - Lucas McClean
-date: 2025-08-18
-updated: 2025-08-18
-collections:
-  - later
-tags:
-  - check-back-later
-readTime: 1
-image:
-  src: ''
-  alt: ''
-published: true
----
-
-Sorry I don’t have anything yet (I mean the page isn’t even styled). I just
-wanted to get the website up and running, but I’ll have some of my writing here
-soon. Thank you for bearing with me and I’ll hope you’ll visit again!
diff --git a/src/articles/introduction-to-go.md b/src/articles/introduction-to-go.md
new file mode 100644
index 0000000..85739ba
--- /dev/null
+++ b/src/articles/introduction-to-go.md
@@ -0,0 +1,424 @@
+---
+title: Introduction to Go
+description: A concise intro to Go, covering its design, syntax, concurrency model, standard library, and ecosystem.
+slug: introduction-to-go
+authors:
+  - Lucas McClean
+reviewers:
+  - Lucas Velasco
+date: 2025-10-15
+updated: 2025-10-15
+tags:
+  - go
+  - golang
+  - beginner
+  - programming
+  - concurrency
+readTime: 12
+image:
+  src: ''
+  alt: ''
+published: true
+layout: article
+---
+
+This article is merely meant as a brief introduction that I hope will encourage
+you to further research Go and its principles. It is far from exhaustive but
+does capture the core ideas of Go and some of the features that I find most
+interesting. I will cover Go's: [Design](#gos-design), [Syntax](#gos-syntax),
+[Ecosystem](#gos-ecosystem), [Standard Library](#gos-standard-library),
+[Concurrency Model](#gos-concurrency-model), and approach to
+[Error Handling](#gos-error-handling). At the end of each section I also add
+resources that I found useful when I was learning Go.
+
+*The only expectation is that you are familiar with programming basics – though
+if you have less experience, I think you will still find most of the article
+digestible.*
+
+*Note: examples target Go 1.25*
+
+## Go's Design
+
+Go is a programming language built around the core principles of **simplicity**,
+**efficiency**, and **concurrency**. Many programming languages prioritize
+expressiveness or control. But Go often makes sacrifices in these areas in
+exchange for clarity and predictable performance.
+
+In my experience, simplicity is the greatest indicator of an effective and
+maintainable code base. The simpler a project is – both architecturally and
+line-by-line – the easier it is for developers to work with it effectively. Go's
+design encourages code that is more readable and maintainable, almost by
+default.
+
+*Resources*: [Go Proverbs](https://go-proverbs.github.io/),
+[Effective Go](https://go.dev/doc/effective_go)
+
+## Go's Syntax
+
+If you're familiar with general programming concepts, then Go shouldn't be too
+difficult to pick up. Its syntax is relatively basic, with just a few key
+differences from other C-like languages.
+
+```go
+package main
+
+import "fmt"
+
+// In Go, types come *after* the variable or function name
+var test int
+
+// Capitalized identifiers (functions, variables, types, etc.)
+// are *exported* (visible outside of the package)
+func Sum(x int, y int) int {
+    return x + y
+}
+
+func main() {
+    // \`range\` can be used to iterate (only as of Go 1.22+)
+    for i := range 5 {
+        // Using formatted output
+        fmt.Printf("%d ", Sum(i, i - 1))
+    }
+
+    // Traditional loop syntax also works:
+    for i := 0; i < 5; i++ {
+        fmt.Printf("%d ", Sum(i, i - 1))
+    }
+
+    // Explicit type declaration
+    var a bool = true
+    // Short variable declaration which infers the type
+    b := false
+
+    // No parentheses around conditions
+    if a || b {
+        fmt.Println("a or b")
+    }
+
+    x := 0
+    // Infinite loop
+    for {
+        if x > 10 {
+            break
+        }
+        x++
+    }
+}
+```
+
+The main *syntactic* differences from other languages:
+
+- No semicolons at the ends of lines
+- Types *after* identifiers in declarations (`x int`)
+- Export via capitalization, rather than a keyword
+- No parentheses are present around conditions
+
+Go doesn't have classes or inheritance. Instead, it uses **structs** for
+grouping data and **methods** (i.e. functions that operate on types) for
+behaviour.
+
+Go's methods look different from methods in many other mainstream languages.
+They are defined outside the struct and use a receiver to specify which type
+they operate on.
+
+```go
+package main
+
+import "fmt"
+
+type Example struct {
+    name string         // unexported (private)
+    isCool bool
+    FavoriteNumber int  // exported (public)
+    SomeArray []int
+}
+
+// Method with value receiver which receives a *copy* of
+// \`Example\`
+func (e Example) PrintName() {
+    // unexported \`name\` still available inside the method
+    fmt.Println(e.name)
+}
+
+func (e Example) PrintInfo() {
+    fmt.Printf("%d %t\n", e.FavoriteNumber, e.isCool)
+}
+
+// Method with pointer receiver which allows modification of
+// the original
+func (e *Example) MakeCool() {
+    e.FavoriteNumber = 42
+    e.isCool = true
+}
+
+// Go doesn't require constructors, but a common convention
+// is to use \`NewType\`
+func NewExample(name string) *Example {
+    return &Example{
+        name:       name,
+        isCool:     false,
+        FavoriteNumber: 67,
+        // Because \`SomeArray\` is omitted, it will default
+        // to \`nil\`
+    }
+}
+
+// The main function runs when a package is executed
+func main() {
+    ex := NewExample("Wyatt")
+
+    ex.PrintName() // Outputs: Wyatt
+    ex.PrintInfo() // Outputs: 67 false
+
+    ex.MakeCool() // Modify through pointer receiver
+    ex.PrintInfo() // Outputs: 42 true
+}
+```
+
+Go automatically handles pointer/value method calls; so you can call both
+`ex.PrintName()` and `ex.MakeCool()` the same way, and Go will handle the
+reference conversion for you.
+
+*Resources*: [Tour of Go](https://go.dev/tour/welcome/1),
+[Go by Example](https://gobyexample.com/)
+
+## Go's Error Handling
+
+I've made this its own section, as I often find a language's approach to error
+handling to be highly indicative of its general principles. Go's approach is
+'errors as values.'
+
+```go
+package main
+
+import (
+    "errors"
+    "fmt"
+)
+
+// Go supports multiple return values
+func canFail(x int) (int, error) {
+    if x <= 5 {
+        return 0, errors.New("x should be greater than 5")
+    } else {
+        return x, nil
+    }
+}
+
+func main() {
+    value, err := canFail(4)
+    if err != nil { // You'll see this check quite often in Go code
+        fmt.Printf("Uh oh: %v\n", err)
+        return
+    }
+    fmt.Printf("Success: %d was big enough!\n", value)
+}
+```
+
+*Resources*: [Working with Errors](https://go.dev/blog/go1.13-errors),
+[Error Handling in Go](https://go.dev/blog/error-handling-and-go)
+
+## Go's Ecosystem
+
+The pillars that Go is built on also affect the package system and community. Go
+developers tend to avoid dependencies if possible and prefer straightforward
+designs. There's a preference for 'obvious' designs, and composition as opposed
+to inheritance.
+
+In most Go codebases, you'll find:
+
+- Shallow directory structures
+- Minimal abstraction
+- Composition over inheritance
+- A preference for plain interfaces and simple tooling
+
+To start a new Go project:
+
+```bash
+# First, install Go from https://go.dev/doc/install
+mkdir my-project
+cd my-project
+go mod init github.com/your-username/my-project
+```
+
+To add a dependency:
+
+```bash
+go get github.com/dependency-owner/dependency-name@latest
+```
+
+To clean up unused or redundant dependencies:
+
+```bash
+go mod tidy
+```
+
+And finally, to run your project:
+
+```bash
+go run .
+```
+
+`go.mod` defines the module path and your direct dependencies and the hashes of
+those dependencies are stored in `go.sum`.
+
+Some other tools you may see:
+
+- `gofmt` / `go fmt`: formatting (Go culture strongly relies on auto-formatting)
+- `go vet` and `staticcheck`: static analysis
+- `go test`: testing
+- `go install pkg@version`: install a binary from a module
+
+*Resources*: [Awesome Go](https://awesome-go.com/),
+[Go Modules Reference](https://go.dev/ref/mod)
+
+## Go's Concurrency Model
+
+In Go, concurrency is first class: it's built right into the syntax of the
+language. The primary tool for concurrency in Go is the **goroutine**.
+
+```go
+package main
+
+import (
+    "fmt"
+    "sync"
+    "time"
+)
+
+func DoSomething(x int, wg *sync.WaitGroup) {
+    // \`defer\` performs the action at the end of the function
+    defer wg.Done()
+	time.Sleep(time.Duration(x) * time.Second)
+	fmt.Printf("Waited for %d seconds\n", x)
+}
+
+func main() {
+    var wg sync.WaitGroup
+
+    for i := range 4 {
+        wg.Add(1)
+        // Simply put \`go\` in front of a function to run it
+        // as a goroutine
+        go DoSomething(i, &wg)
+    }
+
+    // Wait for all goroutines to finish
+    wg.Wait()
+
+    // Both output:
+    // Waited for 0 seconds
+    // Waited for 1 seconds
+    // Waited for 2 seconds
+    // Waited for 3 seconds
+}
+```
+
+The other core concurrency tool is the **channel**. Channels are used for
+communicating between goroutines, and they come with some of their own syntax.
+
+```go
+package main
+
+import (
+    "fmt"
+    "time"
+)
+
+func DoWork(id string, delay int, ch chan string) {
+    time.Sleep(time.Duration(delay) * time.Second)
+    // Put this message into the provided channel
+    ch <- fmt.Sprintf("%s finished after %d seconds", id, delay)
+}
+
+func main() {
+    // \`make\` is used to create channels
+    ch1 := make(chan string)
+    ch2 := make(chan string)
+
+    // Goroutine 1 will finish first and 2 will finish around
+    // three seconds after
+    go DoWork("Goroutine 1", 2, ch1)
+    go DoWork("Goroutine 2", 5, ch2)
+
+    for range 2 {
+        // \`select\` matches on whichever channel is ready
+        select {
+        // \`<-\` used to receive value from channel
+        case msg1 := <-ch1:
+            fmt.Println(msg1)
+        case msg2 := <-ch2:
+            fmt.Println(msg2)
+        }
+    }
+
+    // Outputs:
+    // Goroutine 1 finished after 2 seconds
+    // Goroutine 2 finished after 5 seconds
+
+    // Capacity is specified as last argument to \`make\`
+    buffered := make(chan int, 2)
+    buffered <- 10
+    buffered <- 20
+    close(buffered) // closing signals no more values will be sent
+
+    // 'range' can be used to receive values until the channel closes
+    for val := range buffered {
+        fmt.Printf("Buffered value: %d\n", val)
+    }
+
+    // Outptuts:
+    // Buffered value: 10
+    // Buffered value: 20
+}
+```
+
+*Resources*: [Go 101](https://go101.org/article/channel.html),
+[Go Concurrency Patterns (video)](https://www.youtube.com/watch?v=f6kdp27TYZs),
+[The Go Memory Model](https://go.dev/ref/mem)
+
+## Go's Standard Library
+
+Given the Go community's general opposition to unnecessary dependencies, Go's
+standard library is quite comprehensive – particularly in the areas of I/O and
+networking. It is very often not necessary to look outside the standard library.
+Before adding a dependency, always check
+[Go's Standard Library](https://pkg.go.dev/std) and see if it provides what you
+need.
+
+Some of the big packages:
+
+- `net`: TCP, UDP, HTTP, DNS, Unix sockets, and more (including `net/http`).
+- `io` / `os`: file I/O, environment, `io.Reader`/`io.Writer` patterns.
+- `encoding`: JSON, XML, gob, base64, etc.
+- `crypto`: common cryptographic tools.
+- `testing`: unit tests, benchmarks, and examples.
+
+Long story short: if you need it, Go often has a solid foundation in the
+standard library.
+
+## Further Resources
+
+There's still a lot I didn't cover, and much left to explore. But I hope that
+what I *did* show impressed you enough to continue looking into it. Go is one of
+my favourite programming languages; I find the trade-offs it makes appealing,
+and I love how simple it is to pick up.
+
+**[Tour of Go](https://go.dev/tour/)** is a hands-on tour of the syntax and
+standard library of Go. It walks you through all of its critical components with
+a built-in editor.
+
+**[Effective Go](https://go.dev/doc/effective_go)** provides idioms for common
+patterns. This was probably the resource I found **most useful** in my journey
+learning more advanced Go.
+
+**[pkg.go.dev/std](https://pkg.go.dev/std)** is the standard library
+documentation.
+
+**[Go Blog](https://go.dev/blog/)** covers particular topics. Some topics I
+didn't mention or only briefly mentioned, such as generics, channels,
+concurrency, and advanced error handling, are also worth exploring on the Go
+Blog.
+
+If you have any questions or enjoyed the article, feel free to reach out! You
+can find me on [LinkedIn](https://www.linkedin.com/in/lucasmcclean).
diff --git a/src/lib/articles.ts b/src/lib/articles.ts
index 558fc88..ca52d08 100644
--- a/src/lib/articles.ts
+++ b/src/lib/articles.ts
@@ -7,6 +7,7 @@ const ArticleMetaSchema = z.object({
 	description: z.string(),
 	slug: z.string(),
 	authors: z.array(z.string()),
+	reviewers: z.array(z.string()),
 	date: z.string(),
 	updated: z.string().optional(),
 	tags: z.array(z.string()),
diff --git a/src/lib/components/Link.svelte b/src/lib/components/Link.svelte
index 360148b..045cbbf 100644
--- a/src/lib/components/Link.svelte
+++ b/src/lib/components/Link.svelte
@@ -4,12 +4,14 @@
 
 	const {
 		children,
-		external = false,
+		href = '',
+		external,
 		target,
 		rel,
 		class: className = '',
 		...rest
 	}: HTMLAnchorAttributes & {
+		href?: string;
 		external?: boolean;
 		target?: string;
 		rel?: string;
@@ -17,21 +19,26 @@
 		children: () => unknown;
 	} = $props();
 
-	const computedTarget = external ? '_blank' : target;
-	const computedRel = external ? (rel ?? 'noopener noreferrer') : rel;
+	const isExternal = external ?? /^https?:\/\//.test(href);
+	const isHeadingLink = href?.startsWith('#');
+
+	const computedTarget = isExternal ? '_blank' : target;
+	const computedRel = isExternal ? (rel ?? 'noopener noreferrer') : rel;
 
 
 
 	{@render children()}
-	{#if external}
-		
+	{#if isExternal}
+		
+			
+		
 	{/if}
 
diff --git a/src/lib/components/internal/ArticleLayout.svelte b/src/lib/components/internal/ArticleLayout.svelte
index 1366c49..9859abf 100644
--- a/src/lib/components/internal/ArticleLayout.svelte
+++ b/src/lib/components/internal/ArticleLayout.svelte
@@ -1,3 +1,9 @@
+
+