So I built a portfolio. This one in fact!I’ve added a few more ways to write a message: dictation, writing suggestions, and a Clean up option. You can now talk to the composer, which is usefu
Dustin Snoap
I got hired at TebraI got hired at Tebra as a Software Engineer III. I’d been looking since January and had sent out a couple hundred applications by then. My résumé had
So I built a portfolio. This one in fact!
Dustin Snoap
to you
I’ve started working on a new portfolio after work. The idea is to organize my projects, writing, and updates as email conversations. Most people alre
Dustin Snoap
to you
The backend work I mentioned in the last update is now connected. You can send me a message, create an account, and pick up your conversations on anot
Dustin Snoap
to you
I’ve added a few more ways to write a message: dictation, writing suggestions, and a Clean up option. You can now talk to the composer, which is usefu
I’ve added a few more ways to write a message: dictation, writing suggestions, and a Clean up option. You can now talk to the composer, which is useful when you know what you want to say but would prefer the keyboard handle its own responsibilities.
Dictation runs right in your browser using a small speech-recognition model called Whistle. It downloads when you first use it, then stays cached for later. WebAssembly lets it do the processing on your device, so your microphone audio never needs to travel to a transcription service. I rather like that a browser can now turn speech into text while I’m still occasionally struggling to get it to put a button where I asked.
The writing suggestions give you editable starting points for things like an introduction or a project inquiry. Clean up works on something you’ve already written or dictated, including those occasions when you correct yourself halfway through a sentence and leave both versions there for the reader to negotiate.
Clean up is a separate, optional action that sends the draft text to OpenAI. The audio stays on your device, and you can undo the cleanup if it has misunderstood what you meant. Nothing gets sent to me until you press Send.
The idea is to make writing here a little easier, whether you arrive with a carefully considered question or discover what you’re asking somewhere in the third paragraph. I’d be in a poor position to object to the latter.
Dustin
So I built a portfolio. This one in fact!
I’ve started working on a new portfolio after work. The idea is to organize my projects, writing, and updates as email conversations. Most people already have an inbox they’re avoiding, so naturally I thought I’d give them another one.
There is some reasoning behind this. A project usually needs more explanation than a screenshot and a list of technologies. An inbox gives you a subject and a preview, then leaves you to decide whether you want the rest of the story. I can write as much as the project deserves without making you scroll past all of it to find something else.
For now, I have a skeleton. There’s a place for navigation, a place for messages, and a fairly generous amount of nothing between them. It’s already doing an excellent impression of an inbox nobody has written to.
So I built a portfolio. This one in fact!
The basic layout is coming together. I’ve been working on the sidebar, search bar, category tabs, and message rows in the evenings. There’s a surprising amount of negotiation involved in getting a subject, a preview, and a date to share one line without one of them deciding it owns the place.
I’m keeping the layout familiar because the content should be the interesting part. If someone recognizes how to open a message, switch sections, or search, they can start looking around without first learning how I think a website ought to work.
Projects, Articles, and Updates now have their own tabs. That gives me room for different kinds of writing while keeping the overall experience consistent. It also saves me from trying to explain a backend project and something that happened last Tuesday in the same paragraph.
So I built a portfolio. This one in fact!
I’ve started getting the content into proper conversations. Until now, a lot of the work has involved making convincing places for information to eventually appear.
Each conversation needs enough of a preview to tell you what you’re opening. Once you’re inside, there’s room for the explanation, screenshots, and later updates. I like that a project can keep developing in the same place. The first version doesn’t have to be presented as the final, unquestionable achievement of a person who apparently never changes his mind.
The content is also separate from the interface. Editing a paragraph shouldn’t require spending the rest of the evening remembering which JavaScript function is responsible for displaying it.
This has produced a new problem: I now have to finish writing some of the things I’ve built a website to display.
So I built a portfolio. This one in fact!
Search is working. This seems like a fairly small achievement until you put a search bar at the top of a page and realize you’ve made a promise to everyone who sees it.
It looks through the messages themselves, including the parts that don’t fit in the preview. It also stays within the section you’re browsing. Searching Projects should give you matching projects; it shouldn’t quietly decide that you’d enjoy reading an unrelated update because I happened to use the same word.
I’ve added more specific filters for things like subjects, dates, and message status. Ordinary words still work, which I consider an important feature of a search box.
I’m enjoying this part more than I expected. There’s something satisfying about taking a collection of information and making it easier to get back to. Particularly when you’re the person who put it there and have already forgotten where.
So I built a portfolio. This one in fact!
Compose and Reply now have a working editor. You can write, format text, add links, and include images or attachments. It’s becoming difficult to claim that I’m just making a portfolio with an email theme. I appear to be taking the theme personally.
Both places use the same editor underneath. That matters because a formatting button should behave the same way whether you’re starting a message or replying to one. It also means I can fix a problem once instead of maintaining two slightly different versions of the same mistake.
I’ve been paying attention to the less obvious parts too, like keeping a draft around when you close the composer or look at another conversation. Taking a moment to check something shouldn’t be interpreted as a request to destroy what you were writing.
So I built a portfolio. This one in fact!
Messages and replies are being saved locally, so they survive a refresh. The browser now remembers that you were here, which is more than can be said for some people I’ve been introduced to several times.
I wanted the basic experience to work without asking someone to make an account. You should be able to open the portfolio and use it. Local storage makes that possible while keeping your saved conversations in your browser.
There are limits to that arrangement. Another device won’t have the same history, and clearing the site’s storage clears what’s saved there. Signing in and carrying conversations across devices belongs in the backend work.
For now, I’ve made sure the interface waits for a save to succeed before treating it as successful. If saving fails, your writing stays available. A cheerful confirmation is considerably less useful when it’s describing something that didn’t happen.
So I built a portfolio. This one in fact!
I’ve been working on the mobile layout. Shrinking the desktop version was a useful way to discover how much of the desktop version should not be on a phone.
The navigation moves into a drawer, conversations get the full screen, and the composer uses the space available to it. The aim is to keep the same familiar actions while giving them enough room to be used by a thumb, which has never struck me as a particularly precise pointing instrument.
I’m also keeping mobile behavior separate from desktop preferences. Opening the site on a phone shouldn’t rearrange the reading pane waiting on your computer.
This has been a good reminder that fitting something on a screen and making it usable are two different amounts of work. The first one was finished considerably earlier.
So I built a portfolio. This one in fact!
The frontend is HTML, CSS, and vanilla JavaScript. I’ve kept the work divided into browser modules for things like search, rendering, state, and storage. There’s no framework or build step between the files and the page.
That doesn’t make the organization take care of itself. It just makes it fairly clear who to blame when it doesn’t.
The backend is written in Go. It handles the parts that need a server, including stored conversations, access rules, and uploaded files. Keeping it separate means I can work on the mailbox interface without making every visual adjustment an event involving the database.
The AWS setup is being worked out around S3, DynamoDB, EC2, and CloudFront. Message records and uploaded files have different storage needs, and the public site has different delivery needs from someone’s private conversation. Giving those things separate responsibilities should make the system easier to change without disturbing something unrelated.
So I built a portfolio. This one in fact!
The transitions are getting close to where I want them. I’ve been opening and closing the sidebar, moving between conversations, and watching the same small pieces of the interface more times than I care to explain.
The timing matters. Text shouldn’t appear before there’s room for it, and a panel shouldn’t make you wait while it completes an elaborate entrance. I want the motion to help you follow what changed, then get out of the way.
I’m also respecting reduced-motion preferences and keeping keyboard navigation usable. Looking smooth is one part of the job. Letting someone reach the button is another fairly important one.
These are small changes individually, but the application feels more settled now. I’m reasonably pleased with it, although I suspect I’ve spent enough time watching the sidebar that it would feel rude to say otherwise.
So I built a portfolio. This one in fact!
I’ve added a short sequence of introductory emails. Opening “You probably have some questions” makes “One last thing” arrive. Opening that one brings in “And another thing!”
I could have put them all in the inbox immediately, but then you’d know from the beginning that I wasn’t going to keep my promise. This way, you get to discover that gradually.
The sequence also breaks the introduction into smaller pieces. The first email gets you oriented, the second explains more of the idea, and the third gets into the parts I conveniently neglected to mention.
The portfolio remembers which ones you’ve opened, so returning doesn’t start the introduction over. I’d like people to come back voluntarily, and making them sit through my explanation again seemed unlikely to help.
So I built a portfolio. This one in fact!
I’m getting the portfolio ready to deploy. Most of the recent work has been checking the less impressive things that become very impressive when they fail: navigation, saved messages, narrow screens, loading errors, and whether an unfinished draft stays where you left it.
I’m also drawing a line around this release. The portfolio and local mailbox experience are ready to go out. Real email delivery and signed-in access across devices still need to be connected. Saving a message locally is working, but I don’t want the interface to imply that it has reached my actual inbox until that’s true.
Working on this after work has made it fairly easy to keep finding one more thing to improve. There’s always another spacing adjustment or interaction that could use some attention. At some point, though, a portfolio needs to become a website someone else can visit.
I’m aiming for the 13th. I’ve written that down now, which makes it slightly harder to pretend I meant some other Tuesday.
So I built a portfolio. This one in fact!
I’ve deployed the portfolio.
About three months ago, this was a skeleton I was working on after work. It gradually acquired a layout, conversations, search, an editor, saved messages, a mobile version, and a collection of transitions that have received more personal attention than several household appliances.
The part I’m happiest with is how it all fits together. You can skim the subjects, open something that interests you, and get into the details at your own pace. The interface gives the projects room without requiring every visitor to share my level of interest in them.
There’s still backend work ahead, including real email delivery and account-based synchronization. But the portfolio itself is now somewhere other than the computer I’ve been building it on.
I’m going to spend the rest of the evening looking at it like someone who didn’t write it. This should last until I notice a margin.
So I built a portfolio. This one in fact!
The backend work I mentioned in the last update is now connected. You can send me a message, create an account, and pick up your conversations on another device. Messages and attachments are stored on the server, and I receive an email notification once the conversation has been quiet for fifteen minutes. This gives you a reasonable opportunity to send three corrections before I receive the original.
I’ve also added Norris, an assistant who can answer questions about my projects and work history. He draws from information I’ve supplied and remembers what you’ve been discussing, so you can ask a follow-up without reintroducing the entire subject. There’s a “Forget me” option if you’d like him to start over. It clears his memory and pending replies, rather than removing the conversation you might still want to read.
The mailbox has acquired more of the things people expect from a mailbox. You can organize conversations with your own labels, star something for later, archive it, or use more specific searches to find the message you distinctly remember reading somewhere. Conversations also have shareable links. For actual forwarding, signed-in users can send text to a recipient who has agreed to receive it. One recipient at a time, without attachments or inline images.
I’ve added more control over the reading experience too: colors, fonts, text size, spacing, and where the reading pane sits. The phone version now supports swipe navigation and long-press selection. These are mostly things you notice when they’re missing, which makes them slightly difficult to show off in a screenshot.
The important change is that the portfolio can now support a conversation after you’ve finished reading about my work. You can ask something, come back to it, and find it where you left it.
I’d call that finished, but I have a dated message immediately above this one demonstrating how little authority I have on the subject.
Dustin
Dustin Snoap
Software Engineer III at Tebra
I build backend systems, APIs, and data pipelines, helping computers exchange information without developing
philosophical objections to its format. Previously, I worked at Amazon (Zappos) as a Software Development Engineer.
Have a look around
My projects, writing, and updates are organized as conversations. Browse the tabs or use search to find something
specific. You can get to know my work at your own pace, which is probably preferable to letting me explain a
database until you remember somewhere else you urgently need to be.
Built with
HTML
CSS
Vanilla JavaScript
Browser ES modules and native browser APIs, with zero runtime dependencies.