<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Chris Ellis</title>
    <description>The latest articles on Forem by Chris Ellis (@csellis).</description>
    <link>https://forem.com/csellis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F108923%2F6aebd078-b5b8-4e41-9237-872c94c12dea.jpeg</url>
      <title>Forem: Chris Ellis</title>
      <link>https://forem.com/csellis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/csellis"/>
    <language>en</language>
    <item>
      <title>Moving a Team from React to Svelte</title>
      <dc:creator>Chris Ellis</dc:creator>
      <pubDate>Sat, 05 Nov 2022 09:46:14 +0000</pubDate>
      <link>https://forem.com/csellis/moving-a-team-from-react-to-svelte-5ha7</link>
      <guid>https://forem.com/csellis/moving-a-team-from-react-to-svelte-5ha7</guid>
      <description>&lt;p&gt;Hey, I'm Chris.&lt;/p&gt;

&lt;p&gt;I'm the Director of Engineering at XtendOps, but that's boring. I'll introduce myself later.&lt;/p&gt;

&lt;p&gt;I want to talk about Developer Experience. We all have a feel for what that means and it's easy to talk about if you're a developer. The old saying goes, do things to make your developers' lives easier and you'll have better software.&lt;/p&gt;

&lt;p&gt;We take for granted that good Developer Experience leads to better software. The weird thing is I recently found myself stumbling to describe exactly how to the Leadership at my company. &lt;/p&gt;

&lt;p&gt;How does Developer Experience translate to better software? What does the business experience? Is Business Experience a thing? What does this have to do with Svelte and React?&lt;/p&gt;

&lt;h2&gt;
  
  
  Hey, I'm Chris.
&lt;/h2&gt;

&lt;p&gt;I'm a translator at XtendOps. I translate the Business' needs to the Developers and the Developers' needs to the Business. (I wasn't sure about the apostrophes)&lt;/p&gt;

&lt;p&gt;Let's start with a story. I just came from a 2 week trip to Las Vegas and Mexico. We had a conference in Vegas which was a bit of a coming out party for our company. We help run support for companies like HelloFresh and J. Crew, and we are scaling rapidly.&lt;/p&gt;

&lt;p&gt;After drumming up new business, we went to our offices in Mexico for Leadership meetings. Sounds boring but I got to use a big glass window overlooking the Pacific Ocean as a whiteboard. We were planning out our next 6 months with the CEO and VPs. Post Covid, you tend to forget what developing in an office with other people is like.&lt;/p&gt;

&lt;p&gt;The conversation turned to why we chose to operate in Svelte back in October and that's when I brought up Developer Experience. They looked at me blankly.&lt;/p&gt;

&lt;p&gt;I looked back at them blankly. &lt;/p&gt;

&lt;p&gt;I mean come on, you want your developers to have a good experience right? Am I right?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Revelation
&lt;/h2&gt;

&lt;p&gt;The business doesn't care about Developer Experience. Not in isolation and not for the sake of the developers.&lt;/p&gt;

&lt;p&gt;The business does care about outcomes and at the end of the day outcomes are Business Experience. Its through this lense I want to look at moving from React to Svelte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hey, I'm Chris
&lt;/h2&gt;

&lt;p&gt;I care deeply about Developer Experience (DX) and Business Experience (BX), and that's why we chose Svelte.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conciseness
&lt;/h3&gt;

&lt;p&gt;One of the huge joys of using Svelte is the conciseness of its API. IMHO it provides just enough of an interface to get the job done without bloating your mental landscape of the application with unnecessary abstraction.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your code is your understanding of the problem you're exploring. So it's only when you have your code in your head that you really understand the problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Paul Graham: Y Combinator, &lt;a href="http://paulgraham.com/head.html"&gt;Holding a Program in One's Head&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We put a lot of emphasis on that mental landscape because I have found the more quickly you can digest a complicated frontend view, the quicker you can modify it.&lt;/p&gt;

&lt;p&gt;That feeling you get when you keep reading a component over and over again is an indicator that you have poor abstractions. One thing is not leading to another which means it takes you more cycles to really understand the problem.&lt;/p&gt;

&lt;p&gt;The closeness of Svelte to the browser APIs and its readibility are the DX for why we chose Svelte, but how does this translate to BX.&lt;/p&gt;

&lt;p&gt;Our experience is that it yields faster delivery time with fewer rewrites because of the language. Clarity here is key and appropriate abstractions have reduced our development Lead Times by about 30-40%&lt;/p&gt;

&lt;p&gt;On our first sprint with Svelte, I had chalked it up as a Learning Week. It wasn't going to be about releasing production code that week. (We set aside a whole week of Svelte onboarding giving the team the official Svelte tutorial, example production code, and 2-3 Youtube series.)&lt;/p&gt;

&lt;p&gt;The PRs started coming in after a day and a half. My direct manager and I were completely blown away at the speed with which my team picked it up. I think this speaks to the readibility of Svelte and conciseness. &lt;/p&gt;

&lt;p&gt;This revelation completely altered the development Lead Times we were prepared for and we haven't looked back since.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why tiny matters?
&lt;/h3&gt;

&lt;p&gt;One of the oft spoken about features of Svelte is its tiny bundle size. It's spoken about in very general terms, without quantifying the impact on individuals. It really does matter for our users.&lt;/p&gt;

&lt;p&gt;As an outsourcing company, we hire in the hundreds which means we have thousands of applicants. In addition, our applicants are primarily in Mexico and the Philippines so they are often operating our applications on mobile devices on slower internet compared to the US or Europe.&lt;/p&gt;

&lt;p&gt;I've given all of this context to say that our candidates jobs depend on being able to apply anywhere in the world.&lt;/p&gt;

&lt;p&gt;You may be wondering why this matters for a simple job application form. I'd be wondering the same thing.&lt;/p&gt;

&lt;p&gt;Our clients prize top placements on spoken English and comprehension. With the scale we're operating at, we need to evaluate our candidates before the first interview so we we have custom assessments in the application process.&lt;/p&gt;

&lt;p&gt;How does this affect BX then? We need tiny bundles to run on less powerful devices and ensure the greatest number of applicants.&lt;/p&gt;

&lt;p&gt;We moved to Svelte a year ago and haven't looked back.&lt;/p&gt;

&lt;p&gt;I spoke about this and more at the &lt;a href="https://t.co/n9N5KzQwIB"&gt;Svelte Society London Meetup&lt;/a&gt; back in August.&lt;/p&gt;

&lt;p&gt;Please let me know if you found this helpful.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>react</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Headless Ghost and NextJS</title>
      <dc:creator>Chris Ellis</dc:creator>
      <pubDate>Tue, 30 Mar 2021 16:03:12 +0000</pubDate>
      <link>https://forem.com/csellis/headless-ghost-and-nextjs-5e5e</link>
      <guid>https://forem.com/csellis/headless-ghost-and-nextjs-5e5e</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally posted at &lt;a href="https://chrisellis.dev/writing/headless-ghost-and-nextjs" rel="noopener noreferrer"&gt;chrisellis.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I've taken &lt;a href="https://chrisellis.dev" rel="noopener noreferrer"&gt;chrisellis.dev&lt;/a&gt; headless. When I started my website, I chose Ghost because of its amazing publishing experience. It's pretty great.&lt;/p&gt;

&lt;p&gt;Unfortunately, I found the theme development experience a little bit clunky. Especially when you compare it to something like Gatsby or NextJS.&lt;/p&gt;

&lt;p&gt;So I decided to try out Headless Ghost. Let's see how you can do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create your NextJS App&lt;/li&gt;
&lt;li&gt;Prepare your Ghost Server&lt;/li&gt;
&lt;li&gt;Import use the Content API JavaScript Client to import posts&lt;/li&gt;
&lt;li&gt;Host it on a Serverless Platform&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create your Next App
&lt;/h2&gt;

&lt;p&gt;The first step is to create your NextJS app. You can find more detailed instructions for doing this at NextJS, but the just of it is to do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create your site
yarn create next-app yourdomain.com
cd yourdomain.com

# Start your server
yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare your Ghost Server
&lt;/h2&gt;

&lt;p&gt;This step is a bit more involved. Login to your Ghost site backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FCreatingAPI.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FCreatingAPI.gif" alt="Setup "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to get a &lt;a href="https://ghost.org/docs/content-api/javascript/#installation" rel="noopener noreferrer"&gt;Content API Key&lt;/a&gt; to be able to pull content from our Ghost Site.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click Integrations at the bottom of your Ghost Backend&lt;/li&gt;
&lt;li&gt;Then Add custom integration at the bottom of your Integrations page&lt;/li&gt;
&lt;li&gt;Enter a decent name&lt;/li&gt;
&lt;li&gt;Make note of your Content API Key&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Content API JavaScript Client
&lt;/h2&gt;

&lt;p&gt;Ok, let's start getting fancy and adding a dependency. First, we need to import the Content API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @tryghost/content-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This API is used for fetching content. You can use the Admin API to do more complex things like reading, writing, and editing.  &lt;/p&gt;

&lt;p&gt;I've chosen to extract this out to a /lib folder for reusability. Create a file &lt;code&gt;/lib/posts.js&lt;/code&gt;. We also need to create a .env.local file at the root of your project which NextJS will use for development.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/posts.js
import GhostContentAPI from "@tryghost/content-api";

// Create API instance with site credentials
const api = new GhostContentAPI({
  url: process.env.BLOG_URL,
  key: process.env.API_KEY,
  version: "v3",
});

// .env.local
BLOG_URL="https://yourdomain.com"
API_KEY="f77b5e81e07899d45850bbf248"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now our app will connect to our Ghost Instance.&lt;/p&gt;

&lt;p&gt;To start off with, let's fetch all of the posts so we can list the posts on the index page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/posts.js
export async function getPosts() {
  let posts = await api.posts
    .browse({
      limit: "all"
    })
    .catch((err) =&amp;gt; {
      console.error(err);
    });

  return posts;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in &lt;code&gt;pages/index.js&lt;/code&gt;, we need to import our getPosts() and call it in a getStaticProps. In NextJS, getStaticProps is used to prerender the page at buildtime. Blog posts are a perfect use case for this as they don't change names and slugs very often.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
// top o' the file
...
import { getPosts } from "../lib/posts";

export const getStaticProps = async () =&amp;gt; {
  const posts = await getPosts();

  if (!posts) {
    return {
      notFound: true,
    };
  }
  return {
    props: {
      posts,
    },
  };
};

export default function Home({ posts }) {
  console.log(posts);
...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've set everything up correctly, you should now have a list of all of your published posts in your console from your Ghost site. Switch over to your terminal and you will notice that the posts are logged there as well. This demonstrates that getStaticProps is run during the pre-render at build time.&lt;/p&gt;

&lt;p&gt;Let's display these posts in a list so we can navigate to them. We've already destructured the posts in our Home component so all we have to do is use plain old React patterns to display. Remove everything but the heading inside of . I'll throw mine in an unordered list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
import Link from "next/link";
...
&amp;lt;main className={styles.main}&amp;gt;
  &amp;lt;h1 className={styles.title}&amp;gt;Posts&amp;lt;/h1&amp;gt;
  &amp;lt;ul&amp;gt;
  {posts.map((post) =&amp;gt; {
      return (
        &amp;lt;li key={post.slug}&amp;gt;
          &amp;lt;Link 
            href="/posts/[slug]" 
            as={`/posts/${post.slug}`}&amp;gt;
            &amp;lt;a&amp;gt;{post.title}&amp;lt;/a&amp;gt;
          &amp;lt;/Link&amp;gt;
        &amp;lt;/li&amp;gt;
      );
    })}
  &amp;lt;/ul&amp;gt;
&amp;lt;/main&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note we've also imported the Link component to take advantage of NextJS's routing. Onto the post pages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may have noticed the href and as in the Link component. As is a decorator on the Link and href is the actual link. &lt;a href="https://nextjs.org/docs/api-reference/next/link" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need to create another async function to get a single post by its slug from our Ghost site. Head back over to &lt;code&gt;lib/posts&lt;/code&gt; and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/posts.js
export async function getSinglePost(postSlug) {
  return await api.posts
    .read({
      slug: postSlug,
    })
    .catch((err) =&amp;gt; {
      console.error(err);
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, Next uses file-based routing so let's create a posts folder with a file called &lt;code&gt;[slug].js&lt;/code&gt; in it. This is called a dynamic route in NextJS.&lt;/p&gt;

&lt;p&gt;Next.js provides dynamic routes for pages that don’t have a fixed URL / slug. The name of the js file will be the variable, in this case the post slug, wrapped in square brackets – [slug].js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ghost.org/docs/jamstack/next/#rendering-a-single-post" rel="noopener noreferrer"&gt;Rendering a Single Post&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/posts/[slug].js

import { getSinglePost, getPosts } from "../../lib/posts";

export async function getStaticPaths() {
  const posts = await getPosts();

  const paths = posts.map((post) =&amp;gt; ({
    params: { slug: post.slug },
  }));

  return { paths, fallback: false };
}

export async function getStaticProps(context) {
  const post = await getSinglePost(context.params.slug);

  if (!post) {
    return {
      notFound: true,
    };
  }

  return {
    props: { post },
  };
}

const PostPage = ({ post }) =&amp;gt; {
  return (
    &amp;lt;article&amp;gt;
      &amp;lt;h1&amp;gt;{post.title}&amp;lt;/h1&amp;gt;
      &amp;lt;div dangerouslySetInnerHTML={{ __html: post.html }} /&amp;gt;
    &amp;lt;/article&amp;gt;
  );
};

export default PostPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Walking you through it, we import our data fetching functions.&lt;/p&gt;

&lt;p&gt;Next, we use &lt;code&gt;getStaticPaths()&lt;/code&gt; to get the list of posts that match the given slug. Hint, should only be one.&lt;/p&gt;

&lt;p&gt;Having matched the paths, we pass the matching paths into &lt;code&gt;getStaticProps()&lt;/code&gt; via context so Next knows to render this post at build time.&lt;/p&gt;

&lt;p&gt;Then we just render it like we would in any other React application. Simple, right? 😕&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FResult.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FResult.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've added some styling in the css. You can see the repo at &lt;a href="https://github.com/csellis/headless-ghost-next" rel="noopener noreferrer"&gt;https://github.com/csellis/headless-ghost-next&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's all downhill from here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Host it on a Serverless Platform
&lt;/h2&gt;

&lt;p&gt;The easiest way to manage this is using Vercel's own hosting platform. Vercel owns NextJS so you get to take advantage of the tight integrations.&lt;/p&gt;

&lt;p&gt;I like to use the Vercel CLI as I tend to throw up a lot of small projects. I'll let you follow their install instructions and we'll just go through uploading it to their domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FScreenshot-from-2021-03-23-10-34-36.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fghost.chrisellis.dev%2Fcontent%2Fimages%2F2021%2F03%2FScreenshot-from-2021-03-23-10-34-36.png" alt="Uploading to Vercel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have the CLI setup and logged in, literally just type &lt;code&gt;vercel&lt;/code&gt; and enter a bunch of times.&lt;/p&gt;

&lt;p&gt;And you'll be greeted with an amazing deploy error. I'm so excited.&lt;/p&gt;

&lt;p&gt;Following the link, you'll discover we're missing the environment variables we have in our &lt;code&gt;.env.local&lt;/code&gt; file. Since we're going all CLI here, let's take advantage of the vercel env part of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜  yourdomain.com git:(main) vercel env add
Vercel CLI 21.3.3
? Which type of Environment Variable do you want to add? Plaintext
? What’s the name of the variable? API_KEY
? What’s the value of API_KEY? f77b5e81e07899d45850bbf248
? Add API_KEY to which Environments (select multiple)? Production, Preview, Development
✅  Added Environment Variable API_KEY to Project yourdomain-com [592ms]
Adding API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do the same for both &lt;strong&gt;BLOG_URL&lt;/strong&gt; and &lt;strong&gt;API_KEY&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This time to redeploy we need to run &lt;code&gt;vercel --prod&lt;/code&gt;. Et voilà !&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://yourdomain-com.vercel.app/" rel="noopener noreferrer"&gt;https://yourdomain-com.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've successfully uploaded our Headless Ghost site with NextJS to Vercel. Now you can test the site out before making a full switch to Headless Ghost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;From here you have several options. What I chose to do was host this site on a subdomain while I was working on it over several weekends. You could still visit chrisellis.dev and get to Genuine GhostJS experience.&lt;/p&gt;

&lt;p&gt;When I was happy with the Headless site, I swapped the subdomains around. Reach out to me if you'd like to read about that experience.&lt;/p&gt;




&lt;p&gt;If you want to get more of these posts as soon as they come out, check out &lt;a href="https://chrisellis.dev" rel="noopener noreferrer"&gt;chrisellis.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>ghost</category>
      <category>headless</category>
    </item>
    <item>
      <title>Code under pressure</title>
      <dc:creator>Chris Ellis</dc:creator>
      <pubDate>Sun, 01 Nov 2020 10:05:06 +0000</pubDate>
      <link>https://forem.com/csellis/code-under-pressure-4c16</link>
      <guid>https://forem.com/csellis/code-under-pressure-4c16</guid>
      <description>&lt;p&gt;Don't do it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But the servers are literally on fire.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No, seriously. Don't do it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But I have to.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You're going to regret it. Don't do it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But the C levels are yelling. My job/reputation/company is on the line.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;OK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yell back
&lt;/h2&gt;

&lt;p&gt;For the purposes of this post, we're going to assume you aren't under pressure from your own doing. You have done everything you could possibly do to avoid this circumstance.&lt;/p&gt;

&lt;p&gt;Yell back. If you're client or company is yelling at you about this dumpster fire. Yell back, strategically. And keep it civil.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yell strategically.&lt;/em&gt; They need to fully understand that coding in these situations is prone to error and is dangerous. This should buy you some sympathy, but you know.&lt;/p&gt;

&lt;p&gt;If you have a good idea of what went wrong here, briefly say so. You aren't looking for an argument here, you are planting seeds for what you'll talk about in the retrospective. You will have a retrospective.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep it civil.&lt;/em&gt; Don't yell like an emotional 4 year old. Yell like an adult and calmly. Heightening the emotion of this situation won't make it any better and could make you less effective.&lt;/p&gt;

&lt;p&gt;Dispassionately say what went wrong without assigning blame.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Through a series of unfortunate events, we've ended up down to the wire. I needed the guest list yesterday. Let's fix this if we can.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  We’re Lost, But We’re Making Good Time
&lt;/h2&gt;

&lt;p&gt;Hands off keyboard.&lt;/p&gt;

&lt;p&gt;Don't build when you don't know what you're building. Talk to the stakeholders.&lt;/p&gt;

&lt;p&gt;After you've established that this situation sucks, you need to make sure you're not lost. &lt;em&gt;(That title/quote was Yogi Berra)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Talk to the stakeholders.&lt;/em&gt; Ideally you have a high fidelity talk with them. This at least means a phone call. Even better would be a video call. Even better would be a video call with a screen share.&lt;/p&gt;

&lt;p&gt;Here's why. Text can be misunderstood. It can be misinterpreted. It can be completely omitted. There's not enough time for a back and forth now.&lt;/p&gt;

&lt;p&gt;The video and audio help capture tones and expressions. So when they stress something, you catch it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Know what you're building.&lt;/em&gt; This should be reducible to an ordered bulleted list. While talking to the stakeholder, have them rank the list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OK, in this order we need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the speaker's image&lt;/li&gt;
&lt;li&gt;Add the 25 guests&lt;/li&gt;
&lt;li&gt;Remove the subtitle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yes, but add the guests first&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cut Scope
&lt;/h2&gt;

&lt;p&gt;Let's face it. You might not get all this done in time.&lt;/p&gt;

&lt;p&gt;If you have a little bit of time left, how about start writing your own bucket list&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4HfPLa4W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D1000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4HfPLa4W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D1000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Todo List" width="880" height="585"&gt;&lt;/a&gt;&lt;br&gt;
Photo by &lt;strong&gt;Glenn Carstens-Peters / Unsplash&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's why we had the stakeholder rank the list.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prepare them.&lt;/em&gt; Tell them you will do your best to get these done, but the last few items may not be completed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm going to be heads down coding. I will ping you with each item I get done and I need you to verify promptly. Anything else before I get started?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Head's down
&lt;/h2&gt;

&lt;p&gt;You probably have an idea of what works to make you most productive. Get all of that ready to start.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Take care of yourself.&lt;/em&gt; Are you hungry? Do you need the bathroom? Are you comfortable? These will pull at your attention and focus, take care of these.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Take a breath.&lt;/em&gt; Before you start, close your eyes, take a deep breath in, hold, and exhale. Repeat n number of times until your focus is 💯.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pair if possible.&lt;/em&gt; If you aren't soloing this dungeon, have someone pair with you. Extreme Programming had it right with code quality and this is an extreme situation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code your face off.&lt;/em&gt; With each item ask, what's the quickest way I can do this that's acceptable. Don't introduce security flaws, but also don't test in triplicate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Check for spelling.&lt;/em&gt; You're not done. Check your spelling and don't put curse words in your console. Just say them audibly to get them out of your psyche.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ping the stakeholder.&lt;/em&gt; It's on them. They're your QA now. Move on to the next item. If they ping back, don't check it until you're done with what you're working on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Retrospective
&lt;/h2&gt;

&lt;p&gt;Hopefully, this isn't your first rodeo. Hopefully, it's not your client or C-level's. Also, hopefully, you made it through.&lt;/p&gt;

&lt;p&gt;Be available during the crucial time. If you made it through, the stakeholder will be pleased. If you didn't, you may be called to the front of the class.&lt;/p&gt;

&lt;p&gt;Though it feels like it in the moment, these aren't often as crucial as they seem. Most of the time people have an idea of what they want, but their users have no preconceived notions.&lt;/p&gt;

&lt;p&gt;We do want to avoid these circumstances in the future though. That's why it's vitally important to have a retrospective with the stakeholders.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Congratulate and commiserate.&lt;/em&gt; They're feeling pressure too. Empathy for them can go a long way for future projects. Keep it positive and avoid the blame game. Use objective language, look for points where you could have communicated what you needed sooner, talk about sign offs, and look to the future.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Training the stakeholder.&lt;/em&gt; If you've been working in software for a while, you're familiar with how long things take and what rabbit holes can come up. Your stakeholder isn't.&lt;/p&gt;

&lt;p&gt;They need to recognize we're working with complex information and need time to develop it. There are millions of configurations that are wrong and a much smaller set that are right.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>pressure</category>
      <category>dev</category>
    </item>
  </channel>
</rss>
