> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wrixton.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ryan.war.re: Ryan Warren's Online Resume

> ryan.war.re is Ryan Warren's online resume, detailing his engineering career at Stripe, Amazon, and beyond, built with composable React components.

The resume site at [ryan.war.re](https://ryan.war.re) is Ryan Warren's full online resume — a statically exported Next.js page that lists his technical skills, professional work history, side projects, and education. Like the main site, it uses a root redirect and hosts its content at `/n`.

<Note>
  Visiting `ryan.war.re/` redirects to `ryan.war.re/n` via an HTML `meta` refresh tag, for the same reason as the main site: the project uses Next.js static export with no server available for HTTP-level redirects. A `<noscript>` fallback link is also included on the root page.
</Note>

## Resume Sections

The resume page is divided into four top-level sections, each introduced by an `<Experience>` heading component and populated by one or more `<Activity>` entries.

<CardGroup cols={2}>
  <Card title="Technical Experience" icon="wrench">
    Lists the programming languages, tools, and editors Ryan works with day-to-day, followed by a brief statement of engineering interests.
  </Card>

  <Card title="Relevant Work Experience" icon="briefcase">
    Chronological employment history from his 2012 student tech role at UW through his current Senior Software Engineer position at Stripe.
  </Card>

  <Card title="Related Activities" icon="lightbulb">
    Personal projects and coursework, including the PiDuinoLock hardware project and ongoing web programming experience.
  </Card>

  <Card title="Education" icon="graduation-cap">
    Bachelor of Science in Computer Science and Software Engineering from the University of Washington, graduated June 2015.
  </Card>
</CardGroup>

## Work Experience Entries

The following positions are rendered in reverse chronological order under the **Relevant Work Experience** heading.

| Role                        | Company                  | Team                       | Period                     |
| --------------------------- | ------------------------ | -------------------------- | -------------------------- |
| Senior Software Engineer    | Stripe                   | Internal Tools             | March 2024 – Present       |
| Software Engineer II        | Stripe                   | Internal Tools             | March 2021 – February 2024 |
| Software Engineer II        | Amazon                   | Ads                        | July 2019 – February 2021  |
| Software Engineer           | Amazon                   | Ads                        | July 2017 – June 2019      |
| Software Engineer II        | Porch                    | —                          | August 2016 – July 2017    |
| Software Engineer           | Porch                    | —                          | July 2015 – August 2016    |
| Software Engineer Intern    | Ticketmaster/Live Nation | Commerce, Order Processing | March 2015 – June 2015     |
| Software Engineer Intern    | Ticketmaster/Live Nation | Commerce, Order Processing | June 2014 – December 2014  |
| Web Development Intern      | Sporcle                  | —                          | June 2013 – June 2014      |
| Technical Student Assistant | University of Washington | —                          | June 2012 – October 2013   |

## React Components

The resume is assembled from four custom React components. Each has a narrow, well-defined responsibility.

### `Experience` — Section Heading

The simplest component. It accepts a single `heading` string prop and renders it as an `<h2>`.

```tsx theme={null}
type ExperienceProps = {
  heading: string
}

export default function Experience(props: ExperienceProps) {
  return <h2>{props.heading}</h2>
}
```

Usage in the page:

```tsx theme={null}
<Experience heading={'Relevant Work Experience'} />
```

### `Activity` — Individual Entry

`Activity` is the primary content component. It renders a single job, project, or coursework entry — including the title, company (optionally linked), team name, date range, auto-calculated duration, and a bullet list of accomplishments.

```tsx theme={null}
type ActivityProps = {
  name: string | ReactNode
  company?: string
  team?: string
  start?: string
  end: string
  items: Array<string | ReactNode>
  companyLink?: string
}
```

<Tip>
  The `name` and each entry in `items` accept either a plain `string` or a full `ReactNode`. This allows inline links (via `<ExperienceItem>`) to be embedded directly inside bullet points — for example, referencing Authy for 2FA or Bitbucket for source control.
</Tip>

**Duration calculation.** When a `start` date is provided, `Activity` uses `date-fns` to calculate and display the elapsed time. The string `"Present"` is interpreted as today's date.

```tsx theme={null}
import { intervalToDuration, parse } from 'date-fns'
import pluralize from 'pluralize'

function formatDuration(start: string, end: string): string {
  const endDate =
    end.toLowerCase() === 'present'
      ? new Date()
      : parse(end, 'MMMM yyyy', new Date())

  const interval = intervalToDuration({
    start: parse(start, 'MMMM yyyy', new Date()),
    end: endDate,
  })

  const parts = []
  if (interval.years && interval.years > 0)
    parts.push(`${interval.years} ${pluralize('Year', interval.years)}`)
  if (interval.months && interval.months > 0)
    parts.push(`${interval.months} ${pluralize('Month', interval.months)}`)

  return parts.join(' ')
}
```

The formatted duration is displayed in brackets next to the entry heading — for example, `[3 Years 5 Months]` — and is re-calculated at build time each time the site is deployed.

### `ActivityList` — Bullet List of Accomplishments

`ActivityList` receives the `items` array from `Activity` and renders each entry as an `<li>` inside a `<ul>`. It handles both string and `ReactNode` items transparently.

```tsx theme={null}
type ActivityListProps = {
  items: Array<string | ReactNode>
}

export default function ActivityList(props: ActivityListProps) {
  return (
    <ul>
      {props.items.map((item, idx) => (
        <li key={`activity-list-${idx}`}>{item}</li>
      ))}
    </ul>
  )
}
```

### `ExperienceItem` — Linked Skill or Technology Name

`ExperienceItem` renders either a plain text span or a hyperlink, depending on whether a `url` prop is provided. It is used in two ways:

1. **Inline within `ActivityList` items** — to link third-party tools mentioned in bullet points (e.g., Authy, Nymi, WordPress).
2. **In the Technical Experience section** — to render each technology and editor as a clickable link.

```tsx theme={null}
export type ExperienceItemProps = {
  name: string
  url?: string
}

export default function ExperienceItem(props: ExperienceItemProps) {
  if (props.url) {
    return (
      <a href={props.url} target="_blank" rel="noopener noreferrer">
        {props.name}
      </a>
    )
  }
  return <>{props.name}</>
}
```

## Technical Experience Section

The **Technical Experience** section uses `ActivityList` directly (without an `Activity` wrapper) to display two bullet points. Each technology and editor name in those bullets is rendered as an `<ExperienceItem>` link.

**Technologies listed:**

| Language / Tool | Link                  |
| --------------- | --------------------- |
| Java            | java.com              |
| Ruby            | ruby-lang.org         |
| React           | react.dev             |
| Scala           | scala-lang.org        |
| Go              | go.dev                |
| PHP             | php.net               |
| C++             | cplusplus.com         |
| git             | git-scm.com           |
| Bash            | gnu.org/software/bash |
| MySQL           | mysql.com             |
| PostgreSQL      | postgresql.org        |

**Editors listed:** Claude Code, Cursor, Vim, IntelliJ, vscode

<Note>
  The editors `Claude Code`, `Cursor`, `Vim`, and `IntelliJ` are defined in an `editors` array of `ExperienceItemProps` and mapped into linked items. `vscode` is appended separately after the mapped list as `& vscode`, linked to [code.visualstudio.com](https://code.visualstudio.com/).
</Note>

The second bullet point reads: *"Excited by backend and full stack platform development, with a curiosity for security and AI."*

## Open Graph and Metadata

The resume page configures its `<Head>` with `og:type` set to `profile` (rather than `website`), and includes Open Graph profile fields alongside standard Twitter Card tags.

```tsx theme={null}
<meta property="og:type" content="profile" />
<meta property="og:url" content="https://ryan.war.re/n" />
<meta property="og:title" content="Ryan Warren - Resume" />
<meta property="og:description"
  content="Senior Software Engineer at Stripe. Experienced in Java, Ruby, React, Scala, Go, and more." />
<meta property="profile:first_name" content="Ryan" />
<meta property="profile:last_name" content="Warren" />
<meta property="og:image" content="https://ryan.war.re/og.svg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:site_name" content="War.re" />

<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Ryan Warren - Resume" />
<meta name="twitter:description" content="Senior Software Engineer at Stripe" />

<meta name="keywords"
  content="Ryan Warren, Software Engineer, Stripe, Resume, Java, Ruby, React, Scala, Go, Seattle" />
```

The `robots` and `googlebot` meta tags include `noemailindex` on the resume (unlike the main site), which prevents search engines from indexing the `ryan@war.re` email address that appears in the resume header.
