Why Startups are Like Love Marriages

Or, How to Convince your Parents about Joining a Startup.

Hey guys, and welcome to the latest article on my blogpost. If you’re here due to the click-bait title, I apologize for it, but I wanted to share my thoughts on a topic which came up as a joke in a group chat.

An excerpt from the larger conversation with PII censored.   

My current hypothesis is that Startups are to Love Marriages like MNCs are to Arranged Marriages. So to test this hypothesis, let’s make some arguments towards/for this.

This article is largely based on my own experiences in life, and so is very subjective. If you want actionable advice, it would most likely be better to seek it from someone you know and trust in life. Take everything from here on with a pail of salt.

1. Your Parents Question your Decision to (join a) Startup

The above point being for anyone skipping the traditional campus placement/higher studies and for once trying to do their own thing in life. Indian parents being Indian parents (or parents in general) try to find comparisons in your life with their own lives.

So, your parents, having grown in an India where only large companies existed, don’t understand startups. Where’s the long-term stability? What are your long-term growth prospects? Why don’t you join the MNC with a lavish office and large number of perks and benefits?

In the above question, every question was asked except for the human question. How are the people there? Do you like their vision? Will working there fulfill your passion? Will you be working towards your interests?

Instead of the human reasons why you want to work there, your parents will use the same arbitrary choosing points they used when they were entering the job market (which are at this time and age quite dated). 

While trying to assure or assuade your parents of your decision to (join a) startup, try to reach out to their human side. Tell them, for once, to think of what you like (and are interested in) and make them understand that your decision works out better over the longer term.

And don’t fall into the MNC/FAANG trap either, you’ll most likely be stuck working on legacy projects using legacy tech.

2. With MNCs, there’s no Dating Period

Well there is, if you get an internship, but good luck getting paid a similar amount as the full-time role while working with the same team with similar responsibilities. Other than this route, there's not much else you can do in an MNC to get to know your team earlier.

On the other hand, you can mostly negotiate a probation period in your startup role to have a back-off point in case you don’t like the team or the workplace. 

Use your probation (dating) time to your advantage, by getting to know your colleagues in depth. Learn about their strengths and weaknesses, and most importantly, their life stories.

This will help you make better choices for something you will be doing for the majority of your waking hours, and consequently, for life.

Tip: Don't accept lesser pay for your probation, that's just an internship in sheep's clothing

FIN

Whelp, those were the most defined thoughts I could come up with over the period of a week of thinking. Is this article incomplete? Yes. 

This was a very subjective article so I’ve written based on my life experiences. To add more arguments here, why not comment below or tweet at me?

Subscribe here ✌️😁

Thanks to Madhavi Swamy, Preetam Nath and Deb Mukherjee for giving a draft of this a read!

A Better Way to Structure React Projects

A more standard way of structuring React applications which scales across frameworks and projects.

So 2020 has just come to an end, it was a great year for me personally, I have written more about it on my previous blog post here. To everyone who read through it, thanks a lot. I am trying to share more of my life through my writing and that blog-post was an experiment in that. For further updates you can subscribe to this blog with your email, or follow me on Twitter here.

Apart from it, several people have questions about where I work full-time at. It’s DelightChat, and I couldn’t ask for a better work. Building products from scratch and sharing knowledge across the team without arbitrary constraints is what I thrive in doing.

Because of a far better control over the frontend stack, and having the freedom to experiment with new technologies, I’ve had a better and more deeper understanding of how a React project should be structured for complex applications like the one we’re building here.

And since a lot of e-ink has already been spilt on the relatively easier pickings of “Doing X in React” or “Using React with technology X”, I thought of writing on this topic, which requires a more deeper understanding of React and extended usage in a production setting.

Introduction

In a nutshell, a complex React project should be structured like this. Although I use NextJS in production, this file structure should be quite useful in any React setting.

src
|---adapters
|---contexts
|---components
|---styles
|---pages

Note: In the above file structure, the assets or static files should be placed in whatever the variant of public folder for your framework is.

For each of the above folders, let’s discuss each of them in order of precedence.

1. Adapters

Adapters are the connectors of your application with the outside world. Any form of API call or websocket interaction which needs to happen, to share data with an external service or client, should happen within the adapter itself.

In cases where some data is always shared between all the adapters. Eg, sharing of cookies, base URL and headers across your AJAX (XHR) adapters, it can be initialized in the xhr folder, and then imported inside of your other adapters to be used further.

This structure will look like:

adapters
|---xhr
|---page1Adapter
|---page2Adapter

In the case of axios, you can use axios.create to create a base adapter, and either export this initialized instance, or create different functions for get, post, patch and delete to abstract it further. This would look like:

// adapters/xhr/index.tsx

import Axios from "axios";

function returnAxiosInstance() {
  return Axios.create(initializers);
}

export function get(url){
  const axios = returnAxiosInstance();
  return axios.get(url);
}

export function post(url, requestData){
  const axios = returnAxiosInstance();
  return axios.post(url, requestData);
}

... and so on ...

After you have your base file (or files) ready, create a seperate adapter file for each page, or each set of functionalities, depending on how complex your app is. A well-named function makes it very easy to understand what each API call does and what it should accomplish.

// adapters/page1Adapter/index.tsx

import { get, post } from "adapters/xhr";
import socket from "socketio";

// well-named functions
export function getData(){
  return get(someUrl);
}

export function setData(requestData){
  return post(someUrl, requestData);
}

... and so on ...

But how will these adapters be of any use? Let’s find out in the next section.

2. Components

Although in this section, we should talk about contexts, I want to talk about components first. This is to understand why context is required (and needed) in complex applications.

Components are the life-blood of your application. They will hold the UI for your application, and can sometimes hold the Business Logic and also any State which has to be maintained.

In case a component becomes too complex to express Business Logic with your UI, it is good to be able to split it into a seperate bl.tsx file, with your root index.tsx importing all of the functions and handlers from it.

This structure would look like:

components
|---page1Components
        |--Component1
        |--Component2
|---page2Component
        |--Component1
               |---index.tsx
               |---bl.tsx

In this structure, each page gets its own folder inside of components, so that it’s easy to figure out which component affects what.

It’s also important to limit the scope of a component. Hence, a component should only use adapters for data-fetching, have a seperate file for complex Business Logic, and only focus on the UI part.

// components/page1Components/Component1/index.tsx


import businessLogic from "./bl.tsx";

export default function Component2() {
  
  const { state and functions } = businessLogic();

  return {
    // JSX
  }
}

While the BL file only imports data and returns it

// components/page1Components/Component1/bl.tsx

import React, {useState, useEffect} from "react";
import { adapters } from "adapters/path_to_adapter";

export default function Component1Bl(){
  const [state, setState] = useState(initialState);

  useEffect(() => {
    fetchDataFromAdapter().then(updateState);
  }, [])
}

However, there’s a problem which is common across all complex apps. State Management, and how to share state across distant components. Eg, consider the following file structure:

components
|---page1Components
        |--Component1
               |---ComponentA
|---page2Component
        |--ComponentB

If some state has to be shared across ComponentA and B in the above example, it will have to be passed through all the intermediate components, and also to any other components who want to interact with the state.

To solve this, their are several solutions which can be used like Redux, Easy-Peasy and React Context, each of them having their own pros & cons. Generally, React Context should be “good enough” to solve this problem. We store all of the files related to context in contexts.

3. Contexts

The contexts folder is a bare minimum folder only containing the state which has to be shared across these components. Each page can have several nested contexts, with each context only passing the data forward in a downward direction, but to avoid complexity, it is best to only have a single context file. This structure will look like:

contexts
|---page1Context
        |---index.tsx (Exports consumers, providers, ...)
        |---Context1.tsx (Contains part of the state)
        |---Context2.tsx (Contains part of the state)
|---page2Context
        |---index.tsx (Simple enough to also have state)

In the above case, since page1 may be a bit more complex, we allow some nested context by passing the child context as a child to the parent. However, generally a single index.tsx file containing state, and exporting relevant files should be enough.

I won’t go into the implementation part of React state management libraries since each of them are their own beasts and have their own upsides and downsides. So, I recommend going through the tutorial of whatever you decide to use to learn their best practises.

The context is allowed to import from adapters to fetch and react to external effects. In case of React Context, the providers are imported inside pages to share state across all components, and something like useContext is used inside these components to be able to utilize this data.

Moving on to the final major puzzle-piece, pages.

4. Pages

I want to avoid being biased to a framework for this piece, but in general, having a specific folder for route-level components to be placed is a good practise. Gatsby & NextJS enforce having all routes in a folder named pages. This is quie a readable way of defining route-level components, and mimicking this in your CRA-generated application would also result in better code readability.

A centralized location for routes also helps you utilize the “Go To File” functionality of most IDEs by jumping to a file by using (Cmd or Ctrl) + Click on an import, which helps you move through the code quickly and with clarity of what belongs where. It also sets a clear hierarchy of differentiation between pages and components, where a page can import a component to display it and do nothing else, not even Business Logic.

However, it’s possible to import Context Providers inside of your page so the child components can consume it. Or, in the case of NextJS, write some server-side code which can pass data to your components using getServerSideProps or getStaticProps.

5. Styles

Finally, we come to styles. Although my go-to way is to just embed styles inside of the UI by using a CSS-in-JS solution like Styled-Components, it’s sometimes helpful to have a global set of styles in a CSS file. A plain old CSS file is more shareable across projects, and can also affect the CSS of components which styled-components can’t reach (eg, third-party components).

So, you can store all of these CSS files inside of the styles folder, and import or link to them freely from wherever you wish.

So those were my thoughts. Feel free to email me in case you want to discuss something or have any more inputs on how this can be improved!

For further updates you can subscribe to this blog with your email, or follow me on Twitter here.


Apart from this I’ve been building CAS Parser, a fintech micro-SaaS with Sameer in my free time. If you are confused what a “CAS Parser” is, it’s a tool which allows you to convert CAS (Consolidated Account Statement) PDFs to Excel/CSV/JSON. To learn more, you can read this article.

You can also try out the GUI portal here. Here’s a Youtube video we created to demo that.

Year in Review 2020 🏝

A short retrospective on the past year.

Hey everyone! This was an awesome and confusing year at the same time, so it’s a good time as any to share my story for the past year, and also think of all the things I achieved and would wish to achieve in 2021.

At the start of the year, my mind was set on going for an MS in CS in the US. I was admitted for an MS in CS degree in either University of Utah or University of Virginia. However, March soon came and it was pretty clear that leaving the country wouldn’t be a good option for this year. Luckily (for then), I had the option for deferring admissions to the Fall of 2021.

As I continued working on my job, I started to explore my interest in startups and businesses, and tried to understand what makes a great product, and more importantly, what makes users use and spend money on a product. Through this journey (which sort of started back in 2019 when I was introduced to the Makerlog community), I learned about SaaS products, and how founders bootstrap their own businesses, not primarily to become millionaires, but to serve an audience. These founders eventually end up getting a good MRR, depending on how their business is doing, and so I got introduced to Micro-SaaS (or lifestyle SaaS).

While studying Micro-SaaS, there was this random guy Preetam Nath whose blog I used to study a lot. He managed to grow his business to $33k MRR, which was pretty impressive to me, because the only paid work I had done online till then was paid writing gigs. As it happens, Preetam and his co-founder were hiring at the same time as I was done deferring my college admissions. What happened next, has very really changed the course of my life.

The application process was a simple WhatsApp message with a template, as opposed to the complex job application forms I was used to applying to by then. I had sent the first message near around 10PM at the night, and by 12PM, we had set up an interview for the next morning. From there, the process was pretty fast and clear, they wanted a person capable of building a frontend from scratch (which was a major part of my previous full-time job) and I wanted to learn how to build a viable business from scratch.

The end result was that I became the Founding Engineer and the first full time employee of DelightChat. Soon, we would grow to a team of 5 amazing folk (soon to be 8), and I would be having (and still am) the time of my life building an awesome product.

This wasn’t all, another thing which is taken very seriously here is consistency, and deliberate training. The founders take things like writing and exercise very seriously, and with great consistency, which just compelled me to do the same. So, I started writing more seriously and consistently here, and have also started setting personal goals for myself, hence posts like “VPS Profitability”.

Apart from screen-usage related activities, I had already started reading books more consistently over the past year, and can remember completing at least 7 of them. I’ve also taken up doing at least 15 pushups early in the morning. I am allowed to do more, but a minimum count of at least 15 means that I can also push through on the slow days.

I don’t believe in “New Year Resolutions”, because if I have the chance of improving my life in any way at any point, I believe that I should be capable of doing that from then itself, instead of waiting for an arbitrary position of the Earth around the Sun. However, apart from that sentiment, I do intend to double down on the things I’m already doing well this year, like:

  1. Continue to read more books

  2. Continue writing here, and continuing to work on my personal brand (which may involve moving away from Substack)

  3. Take Twitter more seriously, as a lot of good folk have connected to me from there

  4. Reach that 50 USD goal which I’ve set for myself

  5. Travel more once the situation improves

  6. And, most importantly, have fun in anything I do.


So that’s it for my Year in Review guys! If you like my posts, you can subscribe to this Substack, or follow me on Twitter here.

Information Overload 🤯

How to take control of your time by using code & tech.

Here's a story on how I was overwhelmed by information overload, being stuck to my phone's browser, and how I overcame it in the past 2 weeks. Maybe this could also help someone in the same situation.

The problems which were resulting in me being stuck to my screen were two-fold:

1. Too many Newsletter Subscriptions

Have you faced the situation where your email inbox is lost in a sea of emails. I was stuck in this situation. Whenever I went into my inbox to check a specific email, I used to be stuck in the loop of reading "an interesting email/article".

Pictured: Some interesting articles which I would HAVE to read in case I went through my inbox.

Solution:

I banished all newsletters to Feedly, and organized them into topics. Now, I only go there when I want to catch up on specific newsletters or explore updates from my favorite authors.

Here’s how it looks now:

2. HackerNews Overload 🤖

If you're a complete startup nerd and have been sucked into the YC world, you might have been addicted to HN the same way people get addicted to Instagram or Reddit. Constantly looking for the best posts and updates.

I was the same. Constantly having it open in a tab. In fact, because I liked HN so much I built a screen-reader friendly version of it.

Later, to save my mental energy from constantly checking the front page, I moved to consuming HN from a Telegram Channel. However, the problem with the channel is evident in the image below. The unread count can easily reach 100's in a day or two. Which brings me back to square one.

Solution:

Telegram Bots.

This simple script fetches the previous day's top 20 news items and sends me a message with it. This list is easily readable in 1-2 hours and saves me a lot of time.

const sendHn = async (ids) => {
const currentDate = new Date();
currentDate.setDate(currentDate.getDate() - 1);
const hnResponse = await axios.get(
`https://hn.algolia.com/api/v1/search?tags=story&numericFilters=created_at_i>${
currentDate.valueOf() / 1000
}`
);
const message = `
Today's top HN stories were:
${hnResponse.data.hits
.map(
(hit, index) =>
`\n\n${index + 1}. ${hit.title}\nhttps://news.ycombinator.com/item?id=${
hit.objectID
}\nPoints: ${hit.points}`
)
.join("")}
`;
for (const id of ids) {
bot.telegram.sendMessage(id, message);
}
};
view raw hn.js hosted with ❤ by GitHub

So what am I doing with all of the time I save? Reading. A lot.

I just finished Zero to One (which I felt lacked direction), and am currently speeding through Sapiens (120 pages through in ~3 days).

That’s all folks :). Thanks for reading my thoughts, if you’re interested in receiving my emails in your inbox, why not subscribe below, or subscribe to the RSS feed?

On the road to VPS profitability 📈

A life update

The SuperHero Search API has managed to consistently earn at least 1 paying user over the past year. However, the amount it continues to get is not enough to run a robust VPS, post Paypal + platform taxes.

Although Paul Graham talks about Ramen Profitability [1], it's still at 1500 USD per founder which is a very high goal to set at this stage.

So, I'm aiming for 50 USD pm as my goal for being able to rent a robust lightsail instance or DO droplet comfortably.

This lofty goal (for me, personally) of 50 USD per month would remove the stress of thinking about spending resources on better instances.

And hence, VPS profitability 🔥.

To reach this goal, the products I build will have to:
1. Either convince 10 people that it's worth paying 5 USD a month for,
OR
2. Convince 1 person that it's worth paying 50 USD a month for.

Right now I don't have enough time to build a product which would be worth asking 50 USD for. So, I will be launching a few more APIs over the month to see what works well and what doesn't, and doubling down on what does.

Aside from this, I also worked a little on a tool for my own use in this week, which allows me to maintain context and remember things without switching windows. Check it out in action in the tweet below. Eventually I’ll write on how I solved this problem, and any status updates on the tool.



See you next week. Thanks and bye!

[1] paulgraham.com/ramenprofitable.html

Loading more posts…