Graphite is an open-source CLI and a code review dashboard built for engineers who want to write and review smaller pull requests, stay unblocked, and ship faster.
Tech stack
TypescriptReactExpressPostgresAWS
How engineering
works at Graphite
How are the teams structured?
We are small enough to operate as a single team right now. Despite there being
just nine of us, we’re growing quickly, and soon we’ll have to break out into
multiple teams.
Everyone works in person, full-time at our office in New York. We’re a
tight-knit team who value the ability to huddle over the same desk to check out
a new product or gather around the same whiteboard to tackle a tricky
engineering problem. And when it’s time to take a break, we enjoy lunches in the
neighborhood and one-on-one meetings at local coffee shops, all fully paid for
by our company.
Each quarter, we plan a product roadmap based on user feedback, team ideas, and
business needs. Everyone at Graphite has a say, and engineers can take
individual ownership of goals that fall outside of the roadmap and refine their
own timelines. Our designer and PM work to bring cohesion and support to those
engineers.
What tools do engineers use?
Communication: Slack, Zoom
Internal docs: Notion
Product planning: Linear
Version Control: GitHub
Infrastructure: AWS
Deployment: Github Actions, AWS CodePipelines
Design: Figma
Monitoring and Alerting: Datadog, PagerDuty
Code Review: Graphite
Can developers pick their own tools?
Yes! Bring what you want! Some folks like VSCode, others like heavily customized
Vim. Our only ask is that you use Graphite for code review :)
How does the development process work? What’s the process for working through bugs, features and tech debt?
The team meets weekly for a brief “sprint planning” meeting where each of us
calls out the features they’ll be working on that week, as well as bugs that
need to be prioritized. Collaborative input helps us decide how we spend our
time.
Datadog monitoring quickly alerts us to critical bugs while our bustling Slack
community steers our attention toward smaller bugs and feature requests. We’re
used to people telling us within five minutes of a deployment if they feel like
something’s wrong or could be better. We also have a list where people can add
requests and upvote existing items built into the product. On top of this, we
dogfood Graphite to build Graphite itself.
Across these various inputs, we have a good sense of what bugs need to be worked
on. If it’s critical, the team member who has the most knowledge on the issue
will take the lead and get a fix out. If it’s not critical, we’ll fit it into
weekly sprint planning.
We’re usually aware of common feature requests, thanks to our active and
empowered user base. In the rare case that it’s a feature request we’ve never
heard of, we get a conversation going with the users that raised it. At
Graphite, we believe it’s important to talk to people, understand the
fundamental need that they’re bringing to life, and then prioritize it as a
project in context with other work.
We spend about 15 percent of our time continuously tidying as we build to
address tech debt. We aim to continuously leave the codebase slightly nicer than
we found it rather than letting complexity grow and snowball to a breaking
point.
How does code get reviewed, merged, and deployed?
When engineers create a task, they log it in Linear. At Graphite, you set your
tasks and are responsible for the timelines you set.
When submitting pull requests, engineers use Graphite to create stacks of small
changes. Reviews move fast, and by the time someone submits a new PR, their
previous change likely already has feedback.
We create a continuous flow of small changes that are very quickly merged. It’s
the ethos of our product, but it shows up in how Graphite engineers each and
every one of its features.
What is the QA process?
Instead of manual QA, at Graphite we practice continuous integration (CI) and
test-on-prod.
Every code change is subjected to unit and integration tests prior to merging.
We have reasonable test coverage and use Coveralls to avoid blindspots.
Post-merge, changes trigger a blue-green deployment where we monitor for
increases in errors before committing to the rollout.
Most new features are released behind feature flags. This allows for changes to
be tested first against employees, then select user groups, and finally
everyone. The benefit of building a code review tool is that our own usage
creates sizable canary traffic, and we can often spot bugs before they roll out
to users.
Some companies deploy to QA environments and make engineers manually inspect
their changes while holding up deploy trains. At Graphite, we keep deploy trains
unblocked by either poking features before merge or, after merge behind the
safety of feature flags.
Lastly, if a bug does make its way to users, Datadog monitoring or user reports
in our community Slack alert us to the fact almost immediately. We can either
rollback changes instantly with feature flags or within five minutes on the
server. We could probably move slower and prioritize extreme stability, but at
our current stage we prefer to stay fast and focus on iteration speed.
What are some recent examples of interesting development challenges solved by internal teams as part of building the product?
Displaying massive pull requests used to crush the front-end react rendering
performance. Interactivity, like dragging comment selections and unfurling
files, caused heavy lag. In response, we built custom virtualization (also
referred to as ‘windowing’) into pull request files. This way, Graphite only
renders lines of code visible in the viewport. The result is fewer total DOM
nodes and render performance that’s fast enough for smooth interactivity.
Another recent challenge involved computing code change dependency graphs.
Graphite lets you stack your code changes. That means that any pull request,
open or closed, can link to any other change. For larger repositories, this
might mean traversing hundreds of thousands of changes. Unfortunately, GitHub’s
API only vends PRs at about 10 per second. Our solution was to asynchronously
cache-pull request metadata for repositories. Now, Graphite can decouple network
requests from Github and render change graphs instantly.
As a final example, let’s talk about commenting. With Graphite, we extend
existing code review functionality. On GitHub you can’t comment on a line that
wasn’t changed in that diff. We think that’s silly. You should be able to
comment on any line you want in that file. The challenge with commenting on
unchanged lines is how to sync back to GitHub. We’ve built a system where you
can comment on any line you want on Graphite, but we leave the real comment on
the closest line on GitHub’s end. Within the GitHub comment, we include an
invisible HTML comment containing JSON encoded metadata. On Graphite, we can use
the comment metadata to seamlessly render the comment at its intended location.
How does on-call work?
We use PagerDuty to rotate on-call duty across our small engineering team. We
have thorough observability and monitoring, but we’re strict on keeping page
volume to a minimum. If someone is paged, we’ve made sure it’s critical and
actionable. If it’s not, it should simply be a warning. In practice, that
results in about one page per week. We also constantly respond to users in our
community Slack, but currently, the workload isn’t high enough to require a
formal rotation.
Hiring process at Graphite
How does the application process work? What are the stages and what is the timeline?
We have a standard process for hiring. The whole process can run as fast as
seven days or as slow as a month. It’s entirely dependent on what the candidate
prefers.
Phone screen: Merrill Lutsky, our CEO and co-founder, introduces Graphite
and talks through some of the applicant’s early questions. We also use the
moment to get to know what the candidate has worked on and what they’re
passionate about.
Coffee walk: We have the candidate drop by the office (if possible) and
walk to grab a cup of coffee with the other co-founders. It’s a good moment to
cover the nitty-gritty of what we’re building and how we’re building it.
Depending on the candidate’s timeline, we’ll either have them over for lunch
to meet the team or move straight into interviews.
Interview: We take half a day to run a series of interviews and collect
signal. The interviews can be broken up across multiple days or run over Zoom
depending on the candidate’s preference. We publish a detailed Notion guide
outlining what a candidate can expect from the interviews and we also offer a
take-home alternative to our coding questions. We want to respect the
candidate’s time while also collecting enough signal to make a hiring
decision.
Reference check: Lastly, we conduct reference checks while simultaneously
introducing the candidate to our investors. If all goes well, we then present
an offer and continue meeting to answer any remaining questions.
What’s the career progression framework? How are promotions and performance reviews managed?
We’re big believers in lazy-loading in processes. For now, we’re small enough
where the expectations of our engineers are comparable and therefore we don’t
have promotions and tiers within the engineering team. That being said, we know
roles expand over time and we believe compensation should expand to match.
Currently, we sit down twice a year to review raises. In the near future, as we
reach closer to 15 to 20 employees, we’ll work with the existing team to decide
on a formalized system for feedback both to and from employees.
Console is the place developers go to find the best
tools. Each week, our weekly newsletter picks out the most interesting tools and new releases. We keep
track of everything - dev tools, devops, cloud, and APIs - so you don’t have to.
Subscribe to the weekly Console newsletter
An email digest of the best tools and beta releases for developers. Every Thursday. See the latest email.