Latest / The Pragmatic Engineer / Notion: going native on iOS and Android
Transcript
- 0:00SPEAKER_0: How hard can it be to just render a list?
- 0:02SPEAKER_0: Turns out it's quite complicated, especially because Notion's data model is very complicated.
- 0:06SPEAKER_0: One of the things that people really love about Notion's data model is that if you have a to-do block, you can convert it into a heading or you can convert a heading into a callout.
- 0:14SPEAKER_0: And a lot of these blocks are interchangeable and they're interchangeable in a way that sort of preserves the content in those blocks.
- 0:20SPEAKER_0: And on top of all of this, is that Notion is very reactive.
- 0:24SPEAKER_0: So a lot of the changes that you see or that you make in your Notion workspace are in near real-time reflected on your other devices.
- 0:30SPEAKER_0: So there's a lot of zero to one work that we were doing to build out the real-time connectivity, build out the reactive patterns, and then all while keeping things fast and efficient.
- 0:39SPEAKER_1: Notion is a productivity app and platform with more than a hundred million users.
- 0:43SPEAKER_1: In today's episode, we go to behind the scenes, into the nitty-gritty details of how Notion built its mobile apps.
- 0:49SPEAKER_1: Notion's native iOS and Android mobile apps are used by tens of millions of mobile users and about half of new Notion workspaces are created on mobile.
- 0:57SPEAKER_1: At the same time, Notion's mobile team is surprisingly small, currently 11 engineers evenly split between iOS and Android.
- 1:04SPEAKER_1: For today's conversation, I sat down with two long-tenured engineers on the Notion mobile team.
- 1:09SPEAKER_1: Austin Louden is an iOS engineer and the tech lead manager for Notion's mobile platform.
- 1:13SPEAKER_1: Karn Saheb is a software engineer focused on Android.
- 1:16SPEAKER_1: In today's episode, we cover what the engineering culture is like at Notion and why the mobile team focuses so much on app performance, why Notion decided to rewrite their mobile app from using web views to native components, and why they did this incrementally, Notion's mobile tech stack approach to code reviews, release and testing process and many more details on how the mobile team operates.
- 1:35SPEAKER_1: Whether you're familiar with mobile engineering or you'd like to learn more about how large mobile apps are built and operated, this episode is full of insights, hard to otherwise come by.
- 1:44SPEAKER_1: If you enjoy the show, please subscribe to the podcast on any podcast platform and on YouTube.
- 1:49SPEAKER_1: So today, we have here with us from the Notion team, Karn Saheb and Austin Louden.
- 1:56SPEAKER_1: Welcome to the podcast.
- 1:58SPEAKER_0: Thank you for having us.
- 1:59SPEAKER_2: Yeah, thanks for having us.
- 2:00SPEAKER_1: How is Notion's engineering team different in some ways that you work compared to some of your previous workplaces?
- 2:07SPEAKER_1: I'm kind asking what are some things that feels like it's kind of a unique Notion engineering culture, maybe not as common elsewhere?
- 2:17SPEAKER_2: Yeah.
- 2:17SPEAKER_2: One thing that I haven't seen elsewhere is, just this RFC process where the vast majority of product changes, especially earlier on in Notion's history, were kind of driven by engineers through RFCs or requests for comments.
- 2:34SPEAKER_2: And this meant that kind end-to-end, the product was being driven through engineering essentially.
- 2:41SPEAKER_2: And then those RFCs were shared company-wide where anyone could comment on them, [inaudible 00:02:47] feedback, things like that.
- 2:47SPEAKER_2: I mean, that is the request for comments and that practice has more or less continued today where whenever we want to introduce a new set of changes, it's up to you as the engineer to write out the RFC and then tag everyone that you feel like would have an opinion on this product change for them to review it.
- 3:05SPEAKER_2: We still see engineers driving the process from beginning to end for a lot of futures.
- 3:10SPEAKER_2: So yeah, I think that's something that's fairly unique.
- 3:13SPEAKER_1: Then obviously the document is Notion, right?
- 3:16SPEAKER_1: And the tagging is Notion.
- 3:17SPEAKER_2: Yes, yeah.
- 3:17SPEAKER_1: The comments are Notion.
- 3:19SPEAKER_0: Yeah.
- 3:19SPEAKER_2: Yeah.
- 3:19SPEAKER_0: It's very helpful that everything is in Notion, it just makes it easier to navigate.
- 3:24SPEAKER_2: Yeah, I mean I think that would be one major takeaway.
- 3:28SPEAKER_2: Whether you're using Notion or not, obviously we hope you use Notion, but having one tool that your company is using, the efficiency gains are very difficult to describe.
- 3:37SPEAKER_2: It is just immense because there's no question about where do you create tasks or where do you find a specific document.
- 3:44SPEAKER_2: A hundred percent of it is in Notion.
- 3:47SPEAKER_2: And yeah, that just ends up saving a lot of time in the long run.
- 3:52SPEAKER_0: I think part of the engineering culture to write these RFCs or just documents, and Austin mentioned that anyone can comment.
- 4:02SPEAKER_0: We mean, anyone can comment.
- 4:04SPEAKER_0: For a long time, there weren't a lot of product folks at Notion.
- 4:07SPEAKER_1: Oh.
- 4:08SPEAKER_0: And folks from different functions were in these documents leaving feedback and helping us iterate on the thinking that we had or that we were describing.
- 4:18SPEAKER_0: And whether it's senior leadership or engineering managers or other engineers in different functions or product marketing, growth, everyone was sort of involved in these processes.
- 4:30SPEAKER_0: And I think that part of what made some of our work very successful was that having this sort of high ownership, high buy-in environment for everyone to feel empowered to contribute at this level in the design documents and in the technical specs and say like, "Oh, is this the thing that we want to be building for our users?"
- 4:49SPEAKER_1: This episode is brought to you by DX, a platform that helps organizations measure and improve developer productivity.
- 4:56SPEAKER_1: The DX team includes notable researchers behind the frameworks like DevEx and SPACE, so they're constantly asked by leaders, what metrics should we use to measure developer productivity?
- 5:06SPEAKER_1: To help simplify the landscape, DX just recently published a DX Core 4, a unified framework for measuring developer productivity that encapsulates DORA, SPACE and DevEx.
- 5:17SPEAKER_1: The DX Core 4 includes four dimensions including speed, effectiveness and quality that provide a focus set of metrics that help track productivity at all levels of the organization.
- 5:27SPEAKER_1: You can learn more about the DX Core 4 and how it's being used in companies like Dropbox, Etsy, Vercel and Pfizer at getdx.com/corefour.
- 5:35SPEAKER_1: Again, that's getdx.com/corefour.
- 5:41SPEAKER_1: I imagine there must be a lot of visibility in a sense that it's one thing to have a document that people need to know about.
- 5:46SPEAKER_1: Is it advertised somewhere or just you search or teams have it in a well-known places, or how do you do that or use email?
- 5:54SPEAKER_0: For us, I think now, our process is just like we use internal channels to communicate this and if you're interested in reviewing specs, obviously we're at a stage now where it's not feasible for everyone to have an opinion on things, but now there's internal channels for us to communicate that like, "Hey, here's a new document that we want to get feedback on."
- 6:13SPEAKER_1: So like internal chat channels?
- 6:15SPEAKER_2: Yeah.
- 6:15SPEAKER_0: Exactly.
- 6:16SPEAKER_2: So we have a Slack channel for example, where all major RFCs that are published are shared in that channel and so, there are a lot of folks that are just kind of watching that channel as they come through.
- 6:26SPEAKER_2: We also have rotations where engineers are on the hook for reading all of the RFCs that come through or within a particular domain.
- 6:34SPEAKER_2: And so for a period of maybe six months or so, you might be on kind of this RFC review committee.
- 6:40SPEAKER_2: That way, we ensure-
- 6:42SPEAKER_1: Oh, nice.
- 6:42SPEAKER_2: ... that, yeah, essentially, I think that's necessary to balance things out in that with mobile for example, we used to see a lot of RFCs where there wouldn't be a mobile section at all in the RFC.
- 6:56SPEAKER_2: They would talk about the products, but there would be no mobile considerations.
- 6:59SPEAKER_2: And so now it's helpful having somebody from the mobile team on that review committee that will surface that as an issue if it comes across.
- 7:07SPEAKER_0: Yeah.
- 7:08SPEAKER_0: As teams sort of scale, I think it becomes important to have a distinction between the voices that are important to the decision making and folks who are playing a sort of a supplementary role.
- 7:21SPEAKER_0: And I think the review committee is one example of where we outline these nice boundaries around who's helping make decisions and drive decision making.
- 7:30SPEAKER_1: Yeah, but I'd like to hear how you just added in as it made sense, right?
- 7:34SPEAKER_1: You started with a free form and then you slowly just change it to make it work for you.
- 7:40SPEAKER_1: What are some unique things that the mobile team specifically does at Notion that are part of the mobile engineering culture?
- 7:47SPEAKER_1: And I think earlier you told me there is something around, you have meetings on Mondays?
- 7:55SPEAKER_2: Yeah, we do have a Monday meeting.
- 7:58SPEAKER_2: One thing that probably is unique, at least I haven't seen before is we do a weekly performance review where we look at all of our top line performance metrics like as it's-
- 8:10SPEAKER_1: Also like mobile app performance.
- 8:11SPEAKER_2: Yeah, mobile app performance specifically.
- 8:13SPEAKER_1: Wow, nice.
- 8:16SPEAKER_2: And yeah, I think that just kind of came out of this time period where we really weren't happy with the performance of the mobile apps.
- 8:21SPEAKER_2: And so it's just kind of that mindset where you have to look at the metrics that you want to improve every week to actually get yourself to make progress on them.
- 8:31SPEAKER_2: And so yeah, for the last four years, I would say, we've been looking at our top line mobile metrics, specifically performance related metrics every week.
- 8:40SPEAKER_0: Yeah, the Monday meetings are definitely one of my favorites.
- 8:43SPEAKER_0: I think it's a good way to start up the week and to expand on how we think about meetings.
- 8:50SPEAKER_0: We have two main meetings a week, I think where a lot of companies do daily standups or they have recurring syncs multiple days of the week.
- 8:58SPEAKER_0: But I think at Notion [inaudible 00:09:00], especially on the mobile team, I think we're very much very mindful of the time that engineers have to do heads-down work.
- 9:08SPEAKER_0: There's a lot of interruptions in the day and one meeting at the wrong time slot is, sort of throw off your entire day.
- 9:15SPEAKER_0: And so we have these two main meetings.
- 9:18SPEAKER_0: The Monday sync is a great way for us to catch up, review performance, and then chat about the things that are important to the team.
- 9:25SPEAKER_0: We have this section called the tactical meeting, which is these small items that we want to chat about and we spend two or so minutes in a group setting and then sometimes discussions last longer than that and we move them Async.
- 9:41SPEAKER_0: So it'll be a Slack thread somewhere about a continuity around the thing that we were discussing.
- 9:48SPEAKER_0: And then there's these Thursday syncs that we have, which are projects in progress meetings where we review the work that's being done and how we're moving towards the deliverables that we have for either the sprint or for the milestone or for the project as a whole.
- 10:04SPEAKER_0: Gives us also time to reflect on some of the KTLO work that we're doing and manage external dependencies that we need to be aware of.
- 10:12SPEAKER_0: And then I think my favorite part is demos.
- 10:14SPEAKER_0: We talked about performance a little bit, but as Austin mentioned, we weren't really happy with our performance at a certain point in time.
- 10:23SPEAKER_0: And so some of the things that we built in was, if you're ever looking at a performance regression, one of the things that you do is you demo your investigation in these Thursday syncs.
- 10:33SPEAKER_1: Oh, nice.
- 10:34SPEAKER_0: And that's a good way for us, I think, number one, to share knowledge on how to do these investigations because doing performance investigations are kind of hard and to spread the knowledge and have people ramp up on performance investigations is kind of important.
- 10:49SPEAKER_0: And so these demos are a great way to do that.
- 10:51SPEAKER_0: And there's also design demos and future looking things, which makes the Thursday meeting super exciting.
- 10:58SPEAKER_1: But you mentioned sprints, but you also told me earlier that you don't do sprint planning.
- 11:04SPEAKER_1: How does that add up?
- 11:06SPEAKER_2: Yeah, we don't really formally do sprint planning, but we do have higher level sprint commitments.
- 11:13SPEAKER_2: So we do work on these two week cycles and at the beginning of the two weeks you basically say, what do I want to get done over the next two weeks?
- 11:21SPEAKER_2: And so this is much, much higher than the task level and usually only is two or three bullet points enough to describe, I want to build this section of this feature or eventually later on it gets to the point more of like, I want to ship my feature to Dev or ship it to production, launch the experiment.
- 11:39SPEAKER_2: And then after the two weeks goes by, we'll go through and people will talk about, were they actually able to make progress in their sprint commitments.
- 11:47SPEAKER_2: If they weren't able to make it, what do we not account for?
- 11:51SPEAKER_2: And I think that cadence works out pretty nicely.
- 11:55SPEAKER_1: So would you mind sharing some context on Notion in terms of the number of users you have, how big we can imagine this app to be in complexity, users of that kind of stuff?
- 12:07SPEAKER_2: Yeah, so we recently crossed a hundred million users and we have around tens of millions of users on mobile.
- 12:14SPEAKER_2: About half of new Notion workspaces are created on mobile.
- 12:18SPEAKER_2: So it's a pretty substantial top of funnel for Notion, generally.
- 12:22SPEAKER_2: A lot of users will start on mobile and then potentially move to using it across multiple devices like on desktop, web.
- 12:29SPEAKER_2: In terms of the team, mobile team has 11 engineers and that's roughly split between iOS and Android.
- 12:36SPEAKER_2: Notion altogether has around 600 employees.
- 12:40SPEAKER_1: Wow.
- 12:40SPEAKER_1: So that mobile team is not really big.
- 12:44SPEAKER_1: Is it a more senior team?
- 12:45SPEAKER_1: Is it mix of junior [inaudible 00:12:48]?
- 12:47SPEAKER_1: How can we imagine that?
- 12:49SPEAKER_2: Yeah, so in general, Notion started out pretty senior-heavy, I would say.
- 12:54SPEAKER_2: We wanted to look for folks that were kind of around five plus years of experience to start.
- 12:59SPEAKER_2: And now I would say we're evening out a bit more.
- 13:02SPEAKER_2: We've started an internship program recently and a lot of interns have converted to full-time.
- 13:07SPEAKER_2: So we're getting a bit more of a balance.
- 13:09SPEAKER_2: But initially, yeah, Notion overall was quite senior-heavy.
- 13:12SPEAKER_1: When did Notion first ever have a mobile application?
- 13:16SPEAKER_1: And I understand this was before you joined the company, right?
- 13:18SPEAKER_0: Yeah, I think it was before both of us joined the company.
- 13:21SPEAKER_0: The original Notion mobile apps, I think were around 2017, where we published the first versions of the apps.
- 13:28SPEAKER_0: And they didn't really see a lot of active development until around 2019 when we started investing a little bit more in the mobile experiences.
- 13:35SPEAKER_0: And for a long time, it was just a small wrapper on what is effectively the browser wrap.
- 13:42SPEAKER_1: Can we talk about that?
- 13:43SPEAKER_1: What was this first version of the app?
- 13:46SPEAKER_1: What technology did it use and how was this wrapper around?
- 13:49SPEAKER_1: Was it a WebView wrapper or something else?
- 13:53SPEAKER_2: Yeah, so the initial app used Cordova.
- 13:57SPEAKER_2: So it was effectively just a wrapper around our mobile web app, but for a couple of OS-specific things, we were able to use Cordova to hook into that.
- 14:08SPEAKER_2: And then later on, we moved from Cordova to React Native, although I wouldn't necessarily consider this React Native in the traditional sense.
- 14:16SPEAKER_2: It just used React Native purely for those kind of like OS hooks.
- 14:21SPEAKER_2: So for example, if we wanted to make the app vibrate or something like that, you could use the React Native API for it, but it was predominantly using just a single WebView component that was rendering our mobile WebView essentially.
- 14:36SPEAKER_1: And for people who are not as familiar with Cordova, because these days it's not as popular, would you mind just a refresher of what it is and why not just use the traditional WebView?
- 14:46SPEAKER_1: What advantages did it give at the time?
- 14:49SPEAKER_2: Yeah, so Cordova provides a way of writing cross-platform code to where you don't actually have to write native Swift or Objective-C, Kotlin, Java, and instead, you can just write plain JavaScript and have those hook into native APIs essentially.
- 15:09SPEAKER_2: So it provides a lightweight way of using a WebView predominantly for your app, but then using some of the OS capabilities, like if you wanted to force the phone into landscape or make it vibrate, things like that.
- 15:24SPEAKER_1: So Notion had this app.
- 15:26SPEAKER_1: It sounded like somewhat more simple app back in 2017, and then the two of you joined in 2019 and you decided, "All right, let's do something more native."
- 15:38SPEAKER_1: How did this happen and how did you even make this decision?
- 15:40SPEAKER_1: Because a pretty big decision to say, "We're going from some HTML wrapper, pretty basic stuff.
- 15:46SPEAKER_1: We can reuse a lot of our web logic to starting from what sounds fresh?"
- 15:52SPEAKER_0: Yeah.
- 15:52SPEAKER_0: I mean, you bring up a good point, which is that we already had a bunch of existing work done to make the mobile apps sort of relatively good for the notion experience.
- 16:02SPEAKER_0: And if you've ever used notion, you know that it's a relatively complex product.
- 16:05SPEAKER_0: It's not just text blocks or to-dos, there's collections and embeds, which kind of make it a very complex offering.
- 16:14SPEAKER_0: And so around this time, sort of like 2017, 2018, if you look back at that time and you ask users how they thought about the mobile apps, I think one common complaint you'd probably hear is that the performance wasn't that great.
- 16:29SPEAKER_0: And if you think of using Notion in the way that most people use Notion, so if you're like, especially on your phone where you're like, you might be at the grocery store and you're like, "I need to take down some notes," and put in new grocery items or you're on the go to work and you want to take down some notes, just something to remember, having a sort of poor experience isn't ideal.
- 16:54SPEAKER_0: And it makes it sort of frustrating for users to continue to use a product.
- 17:00SPEAKER_0: So one thing that we want to do is address this performance problem.
- 17:03SPEAKER_0: And a lot of our decision to go to native was premeditated on this idea that if we moved things to native, it would get faster for us.
- 17:14SPEAKER_0: And I remember, I think it was like 2021, sort of the end of the year, we'd sort of come out of this offsite with what we felt like was a sort of crisp vision statement on how we thought we wanted the mobile apps to appear.
- 17:27SPEAKER_0: And what we'd settled on at the time is everything except the editor would be native.
- 17:33SPEAKER_0: And that's kind of like, was our guiding principle going into making things native.
- 17:38SPEAKER_0: And over time, we were building out these tabs, the home tab, the inbox and search tabs, which are kind of the prominent entry points into the different parts of Notion.
- 17:50SPEAKER_0: And we'd started there and we said, "If we slowly convert these to native, we can see the performance benefits."
- 17:57SPEAKER_0: And it was also a good way for us to stress test native.
- 18:01SPEAKER_0: We'd start small, build incrementally and then sort of verify our findings and see if we were actually making the apps better.
- 18:08SPEAKER_0: And what we found was that they were.
- 18:11SPEAKER_0: Moving to native made things better for us.
- 18:14SPEAKER_1: Now, I just want to push you a little bit because I've heard this a lot from mobile engineers say, I'm kind of putting my hat as a CTO on, for example.
- 18:22SPEAKER_1: Mobile engineers come like, "Oh, let's do native because it'll be more performant."
- 18:26SPEAKER_1: But this was around at the time, right?
- 18:28SPEAKER_1: In 2019 or 2020, let's say, a company like Coinbase said, "We are moving away from native because we think React Native is performant enough."
- 18:38SPEAKER_1: What did you look at at performance?
- 18:39SPEAKER_1: What did it mean for you to say, "Okay, we're going to measure this and we're seeing that it is indeed more performant?"
- 18:46SPEAKER_2: Yeah, I think it really comes down to app start time.
- 18:50SPEAKER_2: And so for us, a metric that we look at pretty closely is something we call initial home render, which is just the time it takes from you to tap on the app icon to Notion to appear and all of your items in the home tab to be visible.
- 19:03SPEAKER_2: So we knew that there was effectively a ceiling as to how fast we could make it if we kept the web layer around essentially.
- 19:12SPEAKER_2: And the reason why that's slow is because we have to boot up a WebView and then we have to kind of load our entire app.js bundle.
- 19:21SPEAKER_2: I think there are ways that this could be done a little bit faster if you've modularized to the extent where you're not really loading a large bundle, but we're effectively loading all of Notion when we launch the app, which means, our launch times were a second and a half or two seconds, which is fairly slow for industry standard.
- 19:41SPEAKER_2: And so we felt like we would never really get to the point of an industry standard mobile app without substantially moving the needle.
- 19:51SPEAKER_2: For things like React Native or alternative technologies like that, I think we weren't convinced that we could go as far as we wanted to go without being purely native.
- 20:04SPEAKER_2: I think there's still kind of a ceiling there with those types of technologies, but that wasn't... It didn't really meet where we wanted to go with it.
- 20:13SPEAKER_1: I mean, clearly, there's a ceiling for every technology, but do I sense correctly that what you're saying is that by going native, you can keep it at the bare minimum?
- 20:22SPEAKER_1: You do have the option of cutting back everything.
- 20:26SPEAKER_1: You have to give up a bunch of stuff to have the fastest boot up with the Hello World application, but you can actually control and tweak and make those trade-offs yourself, right?
- 20:35SPEAKER_0: Yeah, I think that's kind of what we were thinking would be the biggest benefits of moving to native is that we'd have more granular control on what exactly our startup path looked like.
- 20:44SPEAKER_0: And if you think about web technologies or just React Native or Cordova for example, they're usually just these shim layers on top of the OS.
- 20:52SPEAKER_0: And it's like anything that we could do to kind of get rid of the shim layers, was an improvement in our part and that would help us improve startup performance.
- 21:00SPEAKER_2: Yeah, especially with... Notion is competing against a lot of personal apps.
- 21:07SPEAKER_2: We compete against Apple Notes and Google Keep, which are all fully native.
- 21:11SPEAKER_2: And so for certain companies like Coinbase you mentioned, it might make sense for them to be able to use something like React Native, but for our market, I feel like if we're competing against Apple Notes, we have to be near to as fast as Apple Notes.
- 21:27SPEAKER_2: Otherwise, we don't really feel like it's feasible.
- 21:29SPEAKER_1: Yeah, or even try to be faster if you can, obviously.
- 21:31SPEAKER_2: Yeah.
- 21:32SPEAKER_1: It's a high bar, [inaudible 00:21:33] but yeah, that makes a lot of sense and I think it's a good reminder, right, of there's no universal things, right?
- 21:41SPEAKER_1: As you said, it depends on who you're competing against, what your priorities are.
- 21:45SPEAKER_1: But one thing that is a bit tricky to do with native development or one of the pushback that most companies have these days is, well, it takes a larger team.
- 21:54SPEAKER_1: How big was the team when you started this project?
- 21:56SPEAKER_1: You told me it's like 10, 11 people, but back when you started, how many of you were there?
- 22:01SPEAKER_1: Was it just two of you?
- 22:02SPEAKER_1: Was it more people?
- 22:03SPEAKER_0: I think it was four people total at the time.
- 22:06SPEAKER_0: It was two iOS, two Android, and a relatively small team to start.
- 22:12SPEAKER_0: But over the course of the projects that we were doing to move things to native, we were also starting to scale the teams.
- 22:20SPEAKER_0: So we didn't kind of do it with four people the entire time.
- 22:24SPEAKER_0: It slowly grew and more people became instrumental to different parts of the project.
- 22:31SPEAKER_1: And can we talk about how this, I guess, rewrite happened?
- 22:34SPEAKER_1: Were you even thinking of it as a rewrite or was it a new project?
- 22:39SPEAKER_1: Because it sounds like you had something, but you kind of slowly moved over to a point where now it's all native or almost all native.
- 22:47SPEAKER_1: How did you even think about this?
- 22:48SPEAKER_2: Yeah, that's right.
- 22:49SPEAKER_2: We were trying to make it incremental in some form, and so we were looking for what is the largest meaning or the smallest meaningful chunk that we could move to native.
- 23:03SPEAKER_2: And for us, that was the home tab.
- 23:06SPEAKER_2: So that's the first thing that you launch into.
- 23:08SPEAKER_2: And so I mentioned earlier, initial home render, that's the most prominent metric in terms of perceived performance of the app.
- 23:17SPEAKER_2: So we started with this home tab slice, and then later on we were able to move to the other tabs.
- 23:23SPEAKER_2: So after that, we shipped search natively and then we shipped inbox natively.
- 23:30SPEAKER_2: But yeah, home tab was kind of the major part of the rewrite because at that point, we had no native code at all.
- 23:37SPEAKER_2: It was purely just the WebView.
- 23:39SPEAKER_2: And so that meant that we had to start from scratch effectively.
- 23:43SPEAKER_2: I remember at the time, we didn't have a way of making authenticated network requests natively, so we literally had to write the network layer, all of the service layers that were required to run Notion to start.
- 23:59SPEAKER_2: So that was kind of what was seen as a rewrite for us because basically, nothing existed at the time, but search and inbox were a little bit easier because we were able to build out the service layer in the meantime.
- 24:13SPEAKER_0: Yeah, I think it's pretty common the industry to hear horror stories about full rewrites taking multiple years, and I think that's a bit of a failure mode that we wanted to guard ourselves against and make sure that we were shipping something that we could complete in a reasonable timeframe.
- 24:31SPEAKER_0: And then also, just vet whether the approach that we were taking was going to work.
- 24:37SPEAKER_0: It was entirely possible that we moved things to native and performance got worse or startup got worse, or it just wasn't compatible in the way that we'd wanted it to work.
- 24:49SPEAKER_0: So yeah, I think that was a common failure mode that we wanted to guard against.
- 24:54SPEAKER_1: And how long did this whole project take?
- 24:58SPEAKER_1: In 2019, you said, "All right, let's start with the home tab," and then later you added search and some of the other things.
- 25:04SPEAKER_1: At what point did you get to the point where either the whole thing was native or most of the thing that matters were native, in your mind, right?
- 25:12SPEAKER_2: Yeah, so the home tab itself took about nine months, and so we started in 2021.
- 25:16SPEAKER_2: We wanted to ship by Christmas.
- 25:19SPEAKER_1: 2021, sorry.
- 25:19SPEAKER_1: Oh, got it.
- 25:20SPEAKER_2: Yeah.
- 25:20SPEAKER_1: So you started to make a plan when you joined like, "All right, we're scheming.
- 25:24SPEAKER_1: We'll try to make something."
- 25:25SPEAKER_2: Yeah.
- 25:26SPEAKER_2: So we knew because of this incremental approach, home tab, once that was shipped, we were able to take a step back and then move to these other tabs later on.
- 25:36SPEAKER_2: End-to-end, that whole process has basically taken four years, but we've shipped other things in the meantime.
- 25:43SPEAKER_2: The home tab project itself was the only part where basically the entire team was working on it and we could do nothing else until it shipped.
- 25:51SPEAKER_2: Effectively, it was blocking everything else on mobile.
- 25:56SPEAKER_1: And just to explain what the home tab is because I have my Notion app here open.
- 26:01SPEAKER_1: Can you tell me why it was, it sounded like it's a big project, but why was it so complex?
- 26:07SPEAKER_1: I just look at it here and obviously, I don't have my inspector on, so I don't see the elements, but I do see recent documents.
- 26:13SPEAKER_1: I do see a lot of quick notes.
- 26:15SPEAKER_1: I do see task lists, et cetera.
- 26:17SPEAKER_0: So the home tab for folks who don't have context into what Notion's home tab looks like is, if you've ever used Notion, there's a bit of a sidebar on the web experience, adjacent to the editor.
- 26:25SPEAKER_0: And the sidebar is like your central navigation hub.
- 26:29SPEAKER_0: It has all the sections for your favorite pages, your shared pages, team spaces, if you're part of larger workspaces.
- 26:38SPEAKER_0: And it's kind of like your central hub for all the information that you have in your particular workspace.
- 26:44SPEAKER_0: So on mobile, that's kind of the home tab.
- 26:46SPEAKER_0: It's that sliver of the Notion experience.
- 26:49SPEAKER_0: It's your entry point into the rest of your work and your documents.
- 26:55SPEAKER_0: And so the obvious thing here is, it's just a list.
- 26:59SPEAKER_0: How hard can it be to just render a list?
- 27:01SPEAKER_1: Right.
- 27:02SPEAKER_0: Turns out, it's quite complicated, especially because Notion's data model is very complicated.
- 27:08SPEAKER_0: One of the things that people really love about Notion's data model is that if you have a to-do block, you can convert it into a heading or you can convert a heading into a call-out.
- 27:17SPEAKER_0: And a lot of these blocks are interchangeable and they're interchangeable in a way that preserves the content in those blocks.
- 27:26SPEAKER_0: Now, this extends to other things like titles.
- 27:28SPEAKER_0: So a common example is you have a title with a mention for today or you have a mention for a particular person, and in other cases, you might have a mention to another page.
- 27:40SPEAKER_0: And so there's this sort of recursive structure that we're starting to build out.
- 27:45SPEAKER_0: And on top of all of this, is that Notion is very reactive.
- 27:49SPEAKER_0: So a lot of the changes that you see or that you make in your Notion workspace are sort of in near real-time reflected on your other devices.
- 27:57SPEAKER_0: So part of what we needed to build was not only just list rendering, but also the reactivity around all the rows and the content that you had in your Notion at home tab.
- 28:10SPEAKER_0: So there's a lot of zero to one work that we were doing to build out the real-time connectivity, build out the reactive patterns, and then all while keeping things fast and efficient.
- 28:19SPEAKER_0: So I know it was going from, what it was effectively nothing to rebuilding Notion's sidebar and navigation primitives.
- 28:29SPEAKER_1: So you built a sidebar, you built navigation.
- 28:31SPEAKER_1: Sounds like you built the real-time processing of events, updating of the UI.
- 28:37SPEAKER_1: Did you do some UI elements or starting the internal design system or that kind of stuff as well?
- 28:43SPEAKER_0: Yeah.
- 28:43SPEAKER_0: I think part of building out these tabs and moving to native, we had to be very intentional about what we wanted to scope as part of the work that we were doing because it could easily blow up into a very large project.
- 28:57SPEAKER_0: And you can think of design systems as being one of those things that are nice to haves, but as a product scales, it becomes more and more important to ensure a consistent experience.
- 29:08SPEAKER_0: And the design system is something that we only built out in the last couple of years.
- 29:12SPEAKER_0: When we first started, we were in an MVP mode, and so a lot of the stuff that we built out was just very bare bones.
- 29:20SPEAKER_0: We were like, "Can we match the specs that we have that's good enough for us?"
- 29:25SPEAKER_2: Yeah.
- 29:26SPEAKER_2: To give another example of the complexity.
- 29:30SPEAKER_2: So Notion is local first in some sense in that when you make edits to a document, we want those to be preserved and then sync later.
- 29:37SPEAKER_2: So there's kind of a similar effect on home tab as well.
- 29:40SPEAKER_2: So one action that you can do is favorite a page.
- 29:44SPEAKER_2: And in most applications, you kind of expect this to be pretty straightforward, where you tap favorites and then it makes an API request with the page that you want to favorite it.
- 29:53SPEAKER_2: But in Notion, this is considered a transaction.
- 29:56SPEAKER_2: And a transaction is like any modification to a piece of data.
- 29:59SPEAKER_2: So if you are typing in a page, you're transforming that text from one state to another state.
- 30:06SPEAKER_2: So favoriting is just an example of another transaction that's possible.
- 30:10SPEAKER_2: So instead of making an API request for this, we needed to build out this whole layer of syncing transactions.
- 30:18SPEAKER_2: So when you favorite a page, we'll create that favorite transaction structure and then we write it to SQLite and then that's periodically flushed.
- 30:28SPEAKER_1: Oh.
- 30:28SPEAKER_1: So you were already building your local data model, right?
- 30:32SPEAKER_1: And I'm assuming later, you would use this in other places as well, obviously?
- 30:36SPEAKER_2: Yep.
- 30:37SPEAKER_1: Okay.
- 30:38SPEAKER_1: Yeah, these are the things, right?
- 30:40SPEAKER_1: I think even I'm sure non-technical people don't always appreciate it and they're asking, why does it take so long for engineering?
- 30:47SPEAKER_1: But even as an engineer, that was a bit surprising to me.
- 30:49SPEAKER_1: And I'm going to ask you a question that's kind of been on my mind since you told me how long the homepage took.
- 30:54SPEAKER_1: What about the editor?
- 30:55SPEAKER_1: If I think of Notion, if I would have to make an educated guess based on what is the most complex part of this application, I would just blurt out, it must be the editor.
- 31:06SPEAKER_1: Because you can add all these things, add all these blocks, there's tables, there's all sorts of text manipulation.
- 31:13SPEAKER_1: I'm sure there's rendering of fonts or scrolling.
- 31:15SPEAKER_1: There's all these hard problems in software engineering.
- 31:19SPEAKER_1: I mean, if you've built something rendering.
- 31:22SPEAKER_1: How does that either compare to the homepage or is it actually easier or is it harder?
- 31:29SPEAKER_1: And where does that fit into the project?
- 31:31SPEAKER_1: To me, it seems like it's just a big part of what you must have built.
- 31:36SPEAKER_2: Yeah, definitely.
- 31:37SPEAKER_2: I think the editor, the reason why we took this approach of sequencing at home tab, search tab and inbox, and then saving the editor for last is because it is the most complex part.
- 31:49SPEAKER_2: And we, so far have built out a few things that will help us when we ultimately would like to get to moving the editor to native as well.
- 31:56SPEAKER_2: So as part of the inbox project, for example, we're beginning to render certain rich text blocks natively.
- 32:03SPEAKER_2: So that means blocks that have code annotations or app mentions, things like that.
- 32:09SPEAKER_2: All of these elements that are part of our text editor normally.
- 32:14SPEAKER_2: So we're already now, I would say, at the phase where there are certain chunks of the editor that we could just kind of do natively, but we need to figure out where the right user experience would be to handle the more complicated parts.
- 32:29SPEAKER_2: So Notion supports these things called collections, which are essentially like mini databases inside of a page.
- 32:36SPEAKER_2: So doing that would be a whole another long project.
- 32:42SPEAKER_2: We also have a lot of embeds.
- 32:43SPEAKER_2: So you can embed Figma designs, for example, within a Notion page, and scrolling in a native view with multiple webviews embedded would be quite complex.
- 32:55SPEAKER_2: So that's another problem that we'll need to deal with at some point.
- 33:00SPEAKER_2: But yeah.
- 33:02SPEAKER_1: That's just a really interesting thing to think about.
- 33:05SPEAKER_1: I'm glad you brought it up because I think it's just not obvious from the outside that this is a game of trade-offs.
- 33:11SPEAKER_1: You have a small engineering team, and for example, now I'm starting to understand why you start with the biggest, the most frustrating parts, the app startup, the home tab.
- 33:22SPEAKER_1: So I think this is a really interesting takeaway for anyone, not even in your domain necessarily, but if you're embarking on a difficult technical challenge, you're leaving the... As an engineer, I would assume that it's most tempting to start with the most complex problem, but the fact that you're phasing it out, actually makes so much sense.
- 33:41SPEAKER_0: I think it was also helpful that part of what made that decision a little bit easier was that we knew that booting up the web app was the slowest part, but once we had the web app booted, it was relatively okay.
- 33:54SPEAKER_0: We could get things going and scrolling was good, but it was that initial sort of chunk that was the most difficult for users.
- 34:02SPEAKER_1: Well, I'm assuming that by having a pretty fast start and having full native control, you can now do stuff in the background, should you want to do that pre-fetch, those kind of things.
- 34:11SPEAKER_0: Yeah.
- 34:11SPEAKER_0: And that's exactly what we do is while you load the home tab, in the background, we're loading the web app so that by the time you click into the page that you want to go to, it's already ready for you.
- 34:23SPEAKER_1: Wow.
- 34:25SPEAKER_1: Super.
- 34:26SPEAKER_1: Now, you're a small mobile team and there will be some people listening who are mobile engineers, but can you explain to us a little bit how you work with other teams and what other teams do you work with on a day-to-day basis, both in terms of engineering teams and non-engineering teams?
- 34:39SPEAKER_1: What does your typical week look like for a more typical mobile engineer at Notion?
- 34:46SPEAKER_2: Yeah, we work pretty closely with other teams.
- 34:48SPEAKER_2: I think our sister team would be probably web infrastructure essentially, because they're also a platform team, although we're kind of in the middle where we support both platform and features.
- 35:00SPEAKER_2: So generally, this plays out through planning where other teams are planning to take on a particular new feature that needs a mobile experience.
- 35:10SPEAKER_2: And so then we try to figure out should these things ship separately.
- 35:15SPEAKER_0: Yeah, I think we're primarily, we sort of function as consultants on these teams just because our bandwidth is a little bit more constrained.
- 35:23SPEAKER_0: And so our job is to help out where we can.
- 35:27SPEAKER_0: And I think it's helpful for us because we've established a bit of a good ownership model.
- 35:32SPEAKER_0: So a lot of web teams are still responsible for their surfaces, specifically the web ones that appear on either mobile web or mobile native.
- 35:40SPEAKER_0: And so we'll continue to provide consulting and make sure that folks are on top of building out features that are compatible with these different form factors.
- 35:50SPEAKER_0: But then there's these native surfaces that we've converted and spent a lot of time building, where we take more of a lead and we'll take the requirements from other teams and figure out how we can best port them into our native infrastructure and build the relevant things that are necessary to carry out those requirements.
- 36:12SPEAKER_1: Interesting.
- 36:12SPEAKER_1: I don't often hear mobile as a consultant setup.
- 36:17SPEAKER_1: It does make sense, right?
- 36:18SPEAKER_1: But I think it just comes to show that every team and every company is different.
- 36:22SPEAKER_1: There is no one size fits all.
- 36:25SPEAKER_1: I am interested to hear a little bit about your mobile development approaches in terms of how iOS and Android work together and what kind of guidelines you set for yourself, may that be code reviews or other engineering approaches?
- 36:37SPEAKER_1: And what kind of collaboration does this pretty small team have within the two big native platforms, which are quite different, right, iOS and Android?
- 36:45SPEAKER_0: I think for a long time, what we did was every feature that we wanted to build, we'd have an Android person working on it and then an iOS counterpart.
- 36:57SPEAKER_0: And this was our approach for a very long time is, let's build things together and build them simultaneously.
- 37:03SPEAKER_0: This would be super helpful because we were a small team.
- 37:06SPEAKER_0: A lot of us would be DRI-ing our own individual projects and collaboration was kind of limited to just the platform that you were working on.
- 37:16SPEAKER_0: And so, to make things a little bit easier and to build on both platforms at the same time, we did these in pairs or at least specifically, the smaller projects that we worked on.
- 37:29SPEAKER_0: These larger projects, the home tab and inbox usually have multiple people working on it, but in terms of our collaboration, at least between the platform teams, like iOS and Android, we tried to do things as much as possible together.
- 37:43SPEAKER_2: Yeah, I'd also say the structure of the apps, we tried to mirror them as closely as we could.
- 37:48SPEAKER_2: Because we were doing this rewrite kind of in tandem, the services and the modules that we created are kind of a one-for-one match on iOS to Android.
- 37:59SPEAKER_2: So the service that interacts with SQLite or the service that syncs our transactions, you can go in the iOS codebase and kind of find roughly a similar file structure as you would see in the Android codebase since these were all kind of planned together.
- 38:15SPEAKER_1: Can we talk about the tech stack, specifically the languages, technologies, frameworks that you're using in iOS and Android and maybe for shared if there's anything shared?
- 38:25SPEAKER_0: Yeah, I think Austin touched on an important part here is that we try to do things a lot very similarly between the two platforms despite having different languages.
- 38:34SPEAKER_0: So our persistence layer is SQLite.
- 38:36SPEAKER_0: It seems sort of ubiquitous across the industry to use some version of SQLite somewhere in your applications-
- 38:43SPEAKER_1: You're saying you're not using core data on iOS?
- 38:46SPEAKER_0: There's small tidbits where we're using these sort of things, but our primary use cases are SQLite for our persistence layer.
- 38:53SPEAKER_0: Obviously, we're a sort of Kotlin/Swift, at least on the mobile side.
- 38:59SPEAKER_0: And then WebView's power, the sort of hybrid portions of the apps.
- 39:05SPEAKER_0: Yeah.
- 39:07SPEAKER_2: Yeah.
- 39:07SPEAKER_2: On iOS, like Karn mentioned, we're using Swift exclusively, except for the parts that are in WebView, which are all in TypeScript.
- 39:14SPEAKER_2: We reply pretty heavily on combine and flows in Kotlin because of the reactivity of Notion.
- 39:21SPEAKER_1: Could you explain what those frameworks do?
- 39:24SPEAKER_2: Yeah, sure.
- 39:25SPEAKER_2: So it's really a way of working with streams of data.
- 39:30SPEAKER_2: So if you've ever worked with Rx, there's RxJava, things like that, reactive pipelines.
- 39:36SPEAKER_2: So it kind of puts you in this mindset of instead of working with a static set of data, that you are working with a stream that is expected to change.
- 39:47SPEAKER_2: So an example that Karn mentioned earlier, if you're looking at your home tab and somebody is updating the title of that page, it will update in real time as you're looking at home tab.
- 39:59SPEAKER_2: And so, it kind of handles re-rendering and things like that or is a way of piping data to the view layer that is reactive.
- 40:08SPEAKER_0: Yeah.
- 40:08SPEAKER_0: I think also in the view layer, we're like Jetpack Compose, SwiftUI, and we're pretty early adopters when we first started some of our migrations to native.
- 40:19SPEAKER_0: We picked Jetpack Compose and SwiftUI as sort of the bets that we had.
- 40:24SPEAKER_1: Oh, but you made that bet early, at least with SwiftUI.
- 40:27SPEAKER_1: It was very new, right?
- 40:28SPEAKER_1: Same with Compose, Jetpack Compose, no?
- 40:30SPEAKER_0: Yeah.
- 40:30SPEAKER_0: Both of them are relatively early, and whether that was the right call I think is just we have a bit of survivorship bias, I guess, because it sort of worked out for us, but it was pretty rough and sometimes building out with these pre 1.0 frameworks, especially for what is effectively the most critical parts of your app.
- 40:54SPEAKER_0: And there's these examples of things that we would do to circumvent issues that we were seeing.
- 41:02SPEAKER_0: So one of the things was Compose was really slow at the start.
- 41:06SPEAKER_0: Performance wasn't a big part of the libraries or the library designs or what they wanted to prioritize.
- 41:16SPEAKER_0: And so we'd see these esoteric bugs show up, like scroll performance would be really bad in certain cases and we would spend time doing these investigations.
- 41:28SPEAKER_0: And one of the things that we found was that materializing the click handlers on these rows was really slow as you were scrolling.
- 41:38SPEAKER_0: And so we'd do these fun hacks to disable the click handlers as you were scrolling.
- 41:43SPEAKER_0: And then once you stop scrolling, we would reattach the click handlers, just so we could get those marginal improvements in performance and work around these weird issues of a pre 1.0 framework.
- 41:55SPEAKER_1: But knowing what you know now that Compose, for example, had these issues, would you still choose it and go around and fix it, or would you just go with something that's kind boring, not as functional, but more stable?
- 42:11SPEAKER_1: Because this is really interesting because when you don't know, you just go with the punches, right?
- 42:16SPEAKER_1: You kind of do it, but would you change it?
- 42:20SPEAKER_0: I think on Android, probably not.
- 42:22SPEAKER_0: I think despite these challenges, I think we made the right bet, in hindsight.
- 42:27SPEAKER_0: I think most of Android development, as least modern development, is moving towards Compose and Kotlin.
- 42:34SPEAKER_0: And so I think being early adopters helped us not only as engineers ramp up on this new framework, but it helped us change the way we thought about building UI, like Jetpack Compose and SwiftUI, declarative UI frameworks.
- 42:50SPEAKER_0: And you sort of build UIs a little bit differently than you would and a good way to, at least to solidify my thinking around this, is that if you asked someone to build a list in Kotlin and you wanted them to... or on Android and you wanted them to use the old XML style versus the new Jetpack Compose style, one of them is way easier to do.
- 43:14SPEAKER_0: And I think that that is just an apt example of how we thought about moving to Compose.
- 43:19SPEAKER_0: I don't know.
- 43:20SPEAKER_0: Austin, what do you think about Swift?
- 43:22SPEAKER_2: Yeah, I would say that we're in a similar position with Swift where it feels like the iOS community is all moving towards SwiftUI.
- 43:29SPEAKER_2: This is where the documentation is all being written, blog posts, this is what Apple was talking about throughout WWDC, and they are making some changes to UIkit, but SwiftUI seems to be their predominant area of focus.
- 43:42SPEAKER_2: So it seems like developers are kind of stuck in this middle ground where they're worried about these risks associated with SwiftUI, but this is where the community seems to be heading.
- 43:52SPEAKER_2: And so I think there's almost a cost to not choosing it at that point because eventually, you will sign yourself up for a rewrite later down the line.
- 44:03SPEAKER_2: But yeah, I would also say that there were some pain points.
- 44:06SPEAKER_2: We had to work around some odd bugs with SwiftUI.
- 44:08SPEAKER_2: 90% of the views I would say were very easy and straightforward to write.
- 44:14SPEAKER_2: And I think that's where there's kind of a major developer velocity improvement with these frameworks, and similar with Jetpack Compose.
- 44:21SPEAKER_2: But then there's that 10% of views where the API doesn't exist yet or there's just some odd bug with it in particular, that may incur quite a bit of cost.
- 44:32SPEAKER_2: But overall, I would still say that I would make the same decision again to go with SwiftUI.
- 44:37SPEAKER_1: But it's encouraging because I think it is good when you can move with the industry and looking back say, "You know what?
- 44:45SPEAKER_1: It was the right call."
- 44:47SPEAKER_1: Because as it sounds like if you chose the existing stuff, UIkit or just XMLs, you would be pushing a migration ahead of you at one point, which will be painful and it's a more mature system.
- 45:03SPEAKER_1: So it's a good reflection.
- 45:05SPEAKER_1: I have to ask you code reviews.
- 45:07SPEAKER_1: Do you do code reviews?
- 45:09SPEAKER_1: Do you do cross iOS/Android code reviews?
- 45:13SPEAKER_1: How do you do it?
- 45:13SPEAKER_1: Because you're such a small team, it's very unique, right?
- 45:17SPEAKER_1: Most mobile teams will, when they're bigger, it's kind of pretty straightforward.
- 45:20SPEAKER_1: Android engineers review Android's code, iOS, iOS, et cetera.
- 45:23SPEAKER_1: There's no cross pollination.
- 45:25SPEAKER_1: What do you do though?
- 45:26SPEAKER_2: Yeah.
- 45:27SPEAKER_2: We'd occasionally do cross-platform code reviews if people are working on the same feature.
- 45:35SPEAKER_2: You're in the scenario where you're writing what's essentially the same set of lines of code across both platforms and you kind of go PR for PR, and so you are kind of in sync with your iOS or Android counterpart throughout that process.
- 45:49SPEAKER_2: But otherwise, I would say maybe 80, 90% of the time, code reviews are done within the platform.
- 45:57SPEAKER_2: But yeah, I would say we follow a fairly standard process.
- 46:01SPEAKER_2: Although, one thing I've noticed at Notion is that we are quite quick on code reviews.
- 46:05SPEAKER_2: We try to keep that timeline from a PR goes up to it being reviewed to be very fast because just that kind of unblocks the next step.
- 46:16SPEAKER_1: So does this mean that people prioritize to stop what they're doing or interrupt their own flow to unblock some, I mean, obviously not as a guideline, but there's a trade-off between, "All right, I'm focused on myself" versus "I'm going to help this person out for a few minutes."
- 46:33SPEAKER_2: Yeah, I think generally people would glance at it right away, and if it's short, then maybe they'll kind of stop what they're doing.
- 46:40SPEAKER_2: For longer PRs though, I would say we try to take about a day or so, SLA.
- 46:45SPEAKER_2: That tends to speed up the whole process.
- 46:49SPEAKER_2: We've also started using a tool called Graphite as well, so people are beginning to stack PRs, and that helps as well.
- 46:57SPEAKER_1: We actually have a deep dive on stacked diffs and on Graphite in the Pragmatic Engineer, so we'll link it into the show notes below.
- 47:04SPEAKER_1: That is awesome to hear.
- 47:06SPEAKER_2: Yeah, I mean, I think that helps because it puts a little bit less pressure on reviewers to kind of get it out right away.
- 47:14SPEAKER_2: And yeah, Graphite is great in that you can pretty easily switch between parts of the stack to update that specific part.
- 47:24SPEAKER_0: One thing I'll add is that I think the mobile team, because it was originally a little bit senior, I think folks would move pretty quickly on the diffs, and I think that was helpful because you don't need to ramp up as much.
- 47:37SPEAKER_0: And then the other real benefit was that because we were a small team, almost everybody was reviewing PRs and by proxy, you would learn a lot about the rest of the codebase because you were just so heavily involved in the code review process and that snowballed.
- 47:52SPEAKER_0: And over time, it would just become easier and easier to review PRs because you had more and more context.
- 47:58SPEAKER_0: And hopefully, we'll see that continue to happen as the teams grow.
- 48:02SPEAKER_0: But I think that's what contributed to things moving a little bit quickly as well.
- 48:07SPEAKER_1: And in terms of engineering practices that also make code reviews easier, what is your take on automated test, linting, static analysis, because there's this trade-off where the more of those things you have A, the slower your builds are, B, the more confidence you might have that if the code review checks all those automated tests, it's probably going to be okay.
- 48:28SPEAKER_1: What balance have you chosen there?
- 48:31SPEAKER_2: Yeah.
- 48:31SPEAKER_2: I would say earlier on throughout this rewrite, we weren't very upfront about writing tests for things that we didn't feel like were very critical, I guess.
- 48:43SPEAKER_2: We would try to write tests for service layer things, so syncing transactions, stuff like that, that we felt like absolutely could not break.
- 48:53SPEAKER_2: Now, I think I'm trying to get us to a point where all of our modules that they're public API or they're public methods that they expose are tested, but that's kind of a long-term idealistic goal, but making slow progress towards that.
- 49:12SPEAKER_0: Yeah.
- 49:12SPEAKER_0: I think we're definitely picking and choosing what we thought was going to work for us in terms of testing and builds.
- 49:19SPEAKER_0: And you mentioned that the trade-off is that over time your bills just become more complicated, and we're a TypeScript shop at Notion as a whole and type checking on Notion just takes a long time because it's a very big codebase, and there's dedicated efforts to make sure that those checks are efficient, both on the TypeScript layer.
- 49:42SPEAKER_0: And for us, in the mobile teams is, code reviews are just one part of developer velocity.
- 49:48SPEAKER_0: The other part is making sure that your changes are merging as quickly as possible because the longer diffs stay open, the more likely there is for merge conflicts, and the more likely that things just drift.
- 50:00SPEAKER_0: So we want to close the gap on those preventable developer velocity issues.
- 50:07SPEAKER_1: Yeah.
- 50:07SPEAKER_1: And there's this saying, which I just made up, but it says, "Never ask a woman her age or a mobile engineer their mobile project compile time."
- 50:16SPEAKER_1: How long does it take to compile the iOS and the Android app from a clean state?
- 50:23SPEAKER_2: Clean, I would say maybe about 45 seconds-
- 50:27SPEAKER_1: Wow.
- 50:28SPEAKER_2: Which is quite fast.
- 50:28SPEAKER_1: That's really fast.
- 50:29SPEAKER_2: Our codebase is still relatively small.
- 50:31SPEAKER_2: Yeah, yeah, it's still relatively small.
- 50:36SPEAKER_2: Both Karn and I have come from companies where the clean build are probably two minutes to even five minutes.
- 50:43SPEAKER_2: But even that, I feel like we're kind of trying to get ahead of it by modularizing to the extent that we do.
- 50:50SPEAKER_2: So we kind of take this approach where every single service, so our network layer, our transaction sync layer, those are all modules that can be built independently and compile time for that is a second, two seconds.
- 51:03SPEAKER_2: And so if you're working in a-
- 51:05SPEAKER_1: That's awesome.
- 51:07SPEAKER_2: Yeah.
- 51:09SPEAKER_2: If you're working in a particular area of the codebase, then you can just kind of switch your target to that module and build it.
- 51:16SPEAKER_2: And potentially that would set us up to migrate to something like Bazel or Buck, if we wanted to in the future.
- 51:25SPEAKER_0: Yeah.
- 51:25SPEAKER_0: I think folks underestimate how important it is to have fast build times.
- 51:30SPEAKER_0: You hear stories of folks who are like, "I hit build on Xcode or entered Studio and then I left to go get coffee," or something because it takes so long.
- 51:40SPEAKER_0: And rapid iteration cycles are a key part of, I think, what engineering culture at Notion is about.
- 51:46SPEAKER_0: So we're very intentional about making sure that we don't regress build performance.
- 51:51SPEAKER_2: Oh, yeah.
- 51:51SPEAKER_2: Another thing that we're kind of putting ourselves in position to do is, instead of just building a particular module, you could even slice out a particular feature and build say, just the home tab for example and all of its dependencies.
- 52:03SPEAKER_1: Wow.
- 52:04SPEAKER_2: I've seen, if you've heard of Point-Free, Brandon Williams, Stephen Celis, they run kind of a iOS video series.
- 52:12SPEAKER_2: But they've talked about this approach where they've kind of carved out specific sets of the app and so they can just build a subset of the app.
- 52:20SPEAKER_2: If you're just working on the home tab for example, you can build that feature and all of its dependencies kind of in a single view.
- 52:26SPEAKER_2: And that's another strategy of just speeding up build times by cutting out all of the unnecessary modules.
- 52:33SPEAKER_1: You mentioned modules.
- 52:34SPEAKER_1: Can you give me a sense how many modules the current Notion app has and when did you introduce these modules?
- 52:40SPEAKER_1: Because it's a lot of work to introduce modularization, and my native approach would be, you sold me, "Oh, the clean build takes 45 seconds.
- 52:48SPEAKER_1: We can probably hold that off until later."
- 52:50SPEAKER_1: But clearly, you didn't do that.
- 52:52SPEAKER_2: Yeah.
- 52:52SPEAKER_2: So the iOS app has about a hundred different modules currently.
- 52:56SPEAKER_2: And what it means to be a module, it's pretty lightweight.
- 53:00SPEAKER_2: Really, we're just defining modules through our package.swf file.
- 53:03SPEAKER_2: And so being a module essentially just means it has its own folder.
- 53:08SPEAKER_2: We explicitly specify its dependencies, what other modules it depends on.
- 53:14SPEAKER_2: And then because it's specified in this way in package.swf, it can be built independently.
- 53:21SPEAKER_2: And we've taken this approach where every unit is either like a feature or a service or a model.
- 53:29SPEAKER_2: It kind of falls into one of these categories.
- 53:32SPEAKER_1: You said, just [inaudible 00:53:34] on what you said, so you said it's either a module, a feature or a service, I understand module.
- 53:40SPEAKER_1: What do you mean by feature or service?
- 53:42SPEAKER_2: Oh.
- 53:42SPEAKER_2: Sorry, to clarify, our modules, all of them kind of fall into these categories.
- 53:48SPEAKER_2: So a module could be a feature or a service or a model.
- 53:51SPEAKER_2: I think that might've been... Yeah.
- 53:53SPEAKER_1: Oh, I understand.
- 53:53SPEAKER_1: So this is the three categories of what a module can be?
- 53:56SPEAKER_2: Yeah.
- 53:57SPEAKER_2: We also have helpers and UI.
- 54:00SPEAKER_2: There are a couple of different categories.
- 54:02SPEAKER_1: I understand.
- 54:03SPEAKER_2: Yeah, generally, its category kind of helps us understand where it might live in the dependency tree.
- 54:09SPEAKER_2: So if it's a helper, ideally it does not have very many dependencies or if it's a model, basically it has no dependencies.
- 54:16SPEAKER_2: But things like features, they're expected to have quite a few dependencies.
- 54:20SPEAKER_2: So they'll depend on services and models and other things.
- 54:24SPEAKER_2: And this way, if you're... This is kind of what helps keep the build time for specific modules very low.
- 54:31SPEAKER_2: Because if you want to build a service, you know that a service is generally only going to depend on maybe some helpers, maybe some models, but nothing higher than that in the dependency tree.
- 54:41SPEAKER_0: On the Android side, I think we're trailing a little bit.
- 54:44SPEAKER_0: I think we're at 50 or so modules.
- 54:46SPEAKER_0: And I think what you asked earlier was how are we thinking about creating these modules?
- 54:51SPEAKER_0: And I think for a long time, especially during the early development of features, we were saying that, "Oh, every new feature would potentially have its own module."
- 55:00SPEAKER_0: And as we built out more features, we would split things out a bit more intentionally.
- 55:06SPEAKER_0: But as Austin mentioned, I think it's kind of lightweight.
- 55:09SPEAKER_0: We'd sort of do it when we think it's the right time to do it.
- 55:13SPEAKER_1: And in Android, do you also have this categorization of model, service, feature, helper?
- 55:19SPEAKER_0: Yeah.
- 55:19SPEAKER_0: I think we try to keep it consistent because it's just helpful to understand the codebase, both as an Android engineer looking at iOS code or an iOS engineer looking at Android code.
- 55:29SPEAKER_0: It's very helpful to have a similar structure despite having different languages.
- 55:34SPEAKER_0: And for us, I think it's the best thing we can do is, sort of keep the gap as close as possible for folks pivoting through the different stacks.
- 55:45SPEAKER_2: Yeah.
- 55:46SPEAKER_2: One other thing it helps with is, you can do migrations on a module by module basis.
- 55:52SPEAKER_2: So for example, Apple just... Or the Swift team just released strict concurrency.
- 56:00SPEAKER_2: And so this is a flag that you can enable to add extra compile time checks for whether or not you're using their concurrency tools in the correct way.
- 56:10SPEAKER_2: And this can be enabled on a module by module basis.
- 56:14SPEAKER_2: So it means that we can incrementally-
- 56:16SPEAKER_1: It's smart.
- 56:16SPEAKER_2: ... go throughout the codebase and turn it on, which makes these types of migrations so much more easier than they would be otherwise.
- 56:23SPEAKER_1: It's interesting because I feel there's, it's not a one-on-one mapping, but there's a little bit of similarities between microservices on the backend or services, depending on how you call it, and modules on mobile, obviously not one-on-one, but both require planning, both have upsize, both have upkeep, but both can, if you do it well, it can just make you go faster as a team.
- 56:46SPEAKER_1: So how do you release, build and release the app?
- 56:49SPEAKER_1: Because this is something, again, as a mobile engineer, I think we know how painful it can be.
- 56:54SPEAKER_1: But as non-mobile, you just see the Notion app appears every week or every two weeks in the app store.
- 57:01SPEAKER_1: What goes behind the scenes of going into that release?
- 57:04SPEAKER_1: There's going to be some sort of builds, QA, some sort of other gates.
- 57:10SPEAKER_1: What steps does it take to get it out there and how often do you push it to the app store?
- 57:14SPEAKER_0: Austin, do you want to take this or?
- 57:19SPEAKER_2: Oh, sure, sure.
- 57:19SPEAKER_2: Yeah.
- 57:20SPEAKER_2: Yeah, so we release the apps once a week and we cut a build on Wednesday nights.
- 57:28SPEAKER_2: We start the release then on Friday, but these are all a progressive rollout, so it sounds kind of odd to release on a Friday, but what we release on Friday is just out to 1% typically.
- 57:39SPEAKER_2: So that's actually kind of the least risky part of the release.
- 57:43SPEAKER_2: Then it kind of picks up.
- 57:44SPEAKER_2: By Monday, we have maybe around 20% or so, and then it increases throughout the rest of the week.
- 57:51SPEAKER_2: One very unique part about Notion is that because we have this hybrid native and web client, we're bundling a version of our app JS when we cut that build on Wednesday, that is continuously upgraded.
- 58:06SPEAKER_2: So one year running Notion, just using it normally, we're checking in the background every once in a while, is there a new version of the web client and then it will download and update that.
- 58:18SPEAKER_2: So our web app is continuously deployed essentially.
- 58:22SPEAKER_2: So at any given time basically, you could have a native version that we know your web app is at least as new as that Wednesday cut, but then potentially, you could have a web version that's a little bit newer, at least a week newer.
- 58:38SPEAKER_2: So that introduces a set of challenges and the differences between those two things that we've tried to have, engineer around.
- 58:44SPEAKER_2: But yeah, that's the general release process.
- 58:50SPEAKER_2: We also have a public beta on TestFlight and the Play Store that releases nightly.
- 58:55SPEAKER_2: So anyone's able to join and we generally enable sets of new features and we're looking at crash logs from those betas a bit more closely.
- 59:05SPEAKER_1: So you have a nightly public beta.
- 59:07SPEAKER_2: That's right.
- 59:08SPEAKER_1: So if people who join the public beta, they will get the nightly cut build.
- 59:12SPEAKER_2: Yeah, that's right.
- 59:13SPEAKER_1: Wow, that's cutting edge.
- 59:14SPEAKER_1: Most companies will do that internally or a lot of companies do that internally, but few would do it externally.
- 59:18SPEAKER_1: That's great to hear.
- 59:21SPEAKER_2: Yeah.
- 59:22SPEAKER_2: Yeah, I think we felt that not having it nightly was not giving us enough signal.
- 59:28SPEAKER_2: I guess, to say that in another way, if we're already releasing once a week, if we were to release a test flight like a public build earlier, then we would only have maybe two or three days of signal and kind of depends on the adoption rate of the build.
- 59:47SPEAKER_2: So yeah, being nightly helps.
- 59:51SPEAKER_0: Yeah.
- 59:53SPEAKER_0: I think some of the benefits of it is also just like it gives us a bit more granular information on what's happening between releases.
- 1:00:01SPEAKER_0: As you can imagine that if you're releasing once a week, there is a bunch of commits going into your code and then that is being rolled out to users.
- 1:00:09SPEAKER_0: And so you effectively have a large chunk of commits going into a single release, and if something regresses, now you have to work backwards from that entire chunk and figure out where things are.
- 1:00:22SPEAKER_0: Having builds go out nightly gives us smaller diffs that are rolling out and helps us detect issues a bit sooner in the release process.
- 1:00:32SPEAKER_1: What is your usage of feature flags?
- 1:00:33SPEAKER_1: Because classic tool and native mobile, because you can only release once a week or few places do more frequently, you could, but there's drawbacks, is you just wrap stuff into feature flags, you do stage rollouts onto them.
- 1:00:47SPEAKER_1: How is your thinking around that or how is your practices around that?
- 1:00:51SPEAKER_0: Yeah, I think it's gotten pretty common in the industry to just heavily rely on feature flags.
- 1:00:55SPEAKER_0: I think gone are the days of six month release cycles where you can vet and build your features in one chunk and then be relatively confident that you're shipping things that work.
- 1:01:07SPEAKER_0: With mobile releases going on every week and nightly for the betas, it means that there's a lot more things that can go wrong and feature flags help us guard against those issues.
- 1:01:20SPEAKER_0: I think at Notion, we use them in a couple of different ways, but I would say primarily we use them to first gate features that are going out or the ones that are being actively developed because the folks are merging PRs, their stuff is sort of being developed behind the scenes.
- 1:01:35SPEAKER_0: And then there's the sort of second type of feature flag, which is something is being rolled out maybe in a staggered rollout, sort of like 10%, 50, whatever, but then we find out that something is going horribly wrong, like there's a particular crash mode that's causing data loss, for example.
- 1:01:50SPEAKER_0: That's a really bad scenario and we want to get ahead of that.
- 1:01:53SPEAKER_0: And because we're doing these weekly releases, we can't have things linger like that in production for that long.
- 1:02:01SPEAKER_0: And so feature flags become sort of a very important mechanism to control these failure modes.
- 1:02:09SPEAKER_1: Can you give a sense of at any given point in time, what the number of feature flags might be roughly we're talking about, in tens or hundreds or even more across the Notion app of active things that are being potentially flagged or the potential to even turn them off if things go wrong?
- 1:02:29SPEAKER_2: Yeah, that would be in the hundreds, I would say.
- 1:02:31SPEAKER_2: I think it's just a general practice.
- 1:02:35SPEAKER_2: If you're developing something, to wrap it in a feature flag.
- 1:02:39SPEAKER_2: And that's probably one of the first things that people generally do when starting a new project, is they'll set up the experiment, set up the feature flag, and then begin development within that.
- 1:02:51SPEAKER_2: So yeah, it just seems to be generally good practice.
- 1:02:57SPEAKER_2: We have a dev environment, so we haven't really touched on deploys yet.
- 1:03:04SPEAKER_2: We have a dev environment that all of the employees are using, and so generally, we enable quite a few feature flags in that environment that are not enabled in production.
- 1:03:16SPEAKER_2: And then we have a staging environment that is tested by QA that mirrors production as closely as possible.
- 1:03:23SPEAKER_1: So just to make it clear, would you mind clarifying how many environments do you have and what they're called?
- 1:03:32SPEAKER_2: Yeah.
- 1:03:33SPEAKER_2: So I guess we have four environments, although they're really three important ones.
- 1:03:37SPEAKER_2: First would be local, and that's just kind of what you're developing on locally.
- 1:03:41SPEAKER_2: The next one would be development.
- 1:03:42SPEAKER_2: And so development is what all of the Notion employees use.
- 1:03:45SPEAKER_2: So whether you're on the mobile apps or on the desktop app, there is a particular environment that hosts kind of our Notion internal workspace that all of employees are working within.
- 1:03:56SPEAKER_2: That's where we get all the [inaudible 01:03:58] feedback from.
- 1:03:59SPEAKER_2: And that is deployed continuously throughout the day, so very frequently.
- 1:04:08SPEAKER_2: Then there's the staging environment that QA tests and that is tested nightly.
- 1:04:13SPEAKER_2: And so they go through a variety of flows, basically making sure that the core experiences are working throughout the app and then there's production.
- 1:04:22SPEAKER_2: And so as we go from dev to staging to production, we try to catch various things throughout the process.
- 1:04:29SPEAKER_2: I would say, the vast majority of things are caught in dev by employees because Notion employees are using Notion to build Notion so heavily, a lot of things are caught in this dev environment.
- 1:04:44SPEAKER_2: And then I would say probably the things that get through are things where you have a feature flag that's enabled in dev that's off in staging, and so then ideally, QA would catch it.
- 1:04:56SPEAKER_2: I would say that that's probably the number one case where things do get through, is employees don't see it because of some kind of feature flag configuration and then it happens to be something that's not covered by QA testing and staging, and then that's how it gets through to production.
- 1:05:12SPEAKER_2: But in general, we're able to catch most things.
- 1:05:15SPEAKER_1: Just to understand, the environments.
- 1:05:17SPEAKER_1: I think it's pretty clear on the backend what it means.
- 1:05:19SPEAKER_1: It's different servers.
- 1:05:21SPEAKER_1: If it's staging, there's services that code is deployed in.
- 1:05:26SPEAKER_1: We're talking about mobile environments, right?
- 1:05:29SPEAKER_1: How is this differentiated?
- 1:05:31SPEAKER_1: Is it a different app that is downloaded or is it based on user different flags being enabled in the environment?
- 1:05:39SPEAKER_1: How can we imagine the difference between the dev environment and production or staging?
- 1:05:47SPEAKER_0: Yeah, I think you're... I mean, a lot of companies do it differently.
- 1:05:51SPEAKER_0: Some folks have the sort of dynamic configuration or depending on the user, it signs you into a different environment.
- 1:05:59SPEAKER_0: But at Notion, we ship different apps.
- 1:06:02SPEAKER_0: We have separate listings on the Play Store and the App Store for these apps, and we ship them to our internal testers, which are just our internal employees.
- 1:06:14SPEAKER_2: Yeah, I think the setup works pretty well because we're able to turn on certain compile time flags when we build those apps.
- 1:06:22SPEAKER_2: So basically, we have a development build of the app and if you ever are using macros, things like that, you can enable those at the very start of the build, essentially.
- 1:06:33SPEAKER_2: And then that is submitted separately.
- 1:06:37SPEAKER_2: So they actually exist as separate entities in App Store Connect and then the Play Store.
- 1:06:40SPEAKER_1: Got it, so [inaudible 01:06:42] environment will be a different binary like a dev compile binary and obviously, combined with a user gets [inaudible 01:06:49].
- 1:06:49SPEAKER_1: If it's an employee, they get different feature flags.
- 1:06:52SPEAKER_2: Yep, exactly.
- 1:06:52SPEAKER_0: Yeah.
- 1:06:53SPEAKER_2: So these apps are just never submitted publicly.
- 1:06:55SPEAKER_1: Makes sense.
- 1:06:55SPEAKER_1: Yeah, yeah.
- 1:06:56SPEAKER_0: There's also a bunch of debugging information that we include like extended logs, more crash reporting.
- 1:07:02SPEAKER_0: So they're a little bit heavier in the sense that we're measuring more things and handling errors a bit differently and the apps that we ship to production are a bit more sort of minified, more efficient, just because our user base is a little bit different.
- 1:07:22SPEAKER_1: But do I understand it correctly that [inaudible 01:07:23] Notion deliberately made this decision to allow for offline work even if the network drops across web and mobile?
- 1:07:33SPEAKER_1: Is this one of the reasons why this quite unusual backend structure and client decisions have been made?
- 1:07:40SPEAKER_1: Or if not, what was the reason?
- 1:07:42SPEAKER_0: Well, with a lot of technical decisions, sometimes it's just historically, that's the decision that was made and that's what we ran with.
- 1:07:51SPEAKER_0: And then you do this long-term evaluation to say whether, oh, it was the right decision, we'll continue to do it this way or we need to rewrite things.
- 1:07:58SPEAKER_0: In our case, I think the model started out like this and to provide a little bit more context, the transactions API or the syncing API is the two major API endpoints that Notion has.
- 1:08:11SPEAKER_0: We don't really have a lot of other ones and these do a majority of the heavy lifting.
- 1:08:15SPEAKER_0: So if you wanted to add things to your favorites or create a new block, all these kind go through that singular safe transactions API, which is what we hit.
- 1:08:24SPEAKER_0: And the request that we're sending is super flexible, so it supports a wide variety of use cases.
- 1:08:31SPEAKER_0: And the same thing is true for syncing is we can just fetch that data.
- 1:08:35SPEAKER_0: And so to your earlier question, was this an intentional decision that we made and chose it to be offline or to support offline better?
- 1:08:45SPEAKER_0: I think as Austin mentioned, I think it was part of the motivation around it, but also we just wanted to support this super flexible data model and have it be able to handle these cases that are sort of core to a user's workflow.
- 1:09:00SPEAKER_0: So you can think of a good example being that Notion is A, you're saving a lot of your knowledge and content there.
- 1:09:08SPEAKER_0: You want some guarantees about where that information is going to be stored and having things fail when you're trying to save them, like take notes, feels like a really bad user experience.
- 1:09:20SPEAKER_0: So we wanted to adjust for that and then build it out upfront.
- 1:09:25SPEAKER_1: It's just fascinating how important the data model is for years later.
- 1:09:29SPEAKER_1: It's just an interesting learning that I would've not thought about it, but it kind of makes sense, right?
- 1:09:36SPEAKER_1: If a product is successful, as successful as Notion has been, it's going to be around and the documents, well, hopefully, there'll be users who've been using it from day one, working on the same documents even.
- 1:09:46SPEAKER_1: And you need to support that.
- 1:09:47SPEAKER_0: Yeah.
- 1:09:48SPEAKER_0: And if you think about the counterpoint, which is that we talked about trade-offs a little bit, but Notion's data model being this flexible, also makes it a little bit difficult to do other things that users might expect us to be able to do.
- 1:10:01SPEAKER_0: And so you're always deciding what is the layer that you want to operate in and what decisions do you want to make to support these core use cases that are important to the product that you're building.
- 1:10:14SPEAKER_1: Taking a step outside of Notion, where do you see the mobile engineering industry heading?
- 1:10:20SPEAKER_1: If we, let's say try to forecast for the next five years, and what areas do you think we're going to see progress on Android and on iOS?
- 1:10:28SPEAKER_1: If you want to start, Austin?
- 1:10:31SPEAKER_2: Yeah, sure.
- 1:10:32SPEAKER_2: The first thing that comes to mind for me is a mobile app architecture.
- 1:10:37SPEAKER_2: Karn mentioned earlier the switch to Jetpack Compose and SwiftUI, these declarative frameworks that I feel like fit with a little bit different of a model.
- 1:10:47SPEAKER_2: They're closer to React than they are to what we have been working with historically on mobile.
- 1:10:54SPEAKER_2: For example, at the time SwiftUI was released, I think the predominant architecture pattern was MVVM, Model-View-ViewModel, that came from model-view-controller.
- 1:11:09SPEAKER_2: But now I see it much more frequently people using a store/Redux pattern that you see on the web, where you have some store class that holds a state struct or something like that and then you might even add on a reducer to handle the actions.
- 1:11:30SPEAKER_2: And I think that's just a byproduct of the way that Compose and SwiftUI handle view re-rendering as a process of state changes to state.
- 1:11:40SPEAKER_2: So I feel like that gives you a lot more control out of state changes.
- 1:11:45SPEAKER_2: And I also feel like it's nice in that we're getting closer to parity with web in terms of architecture.
- 1:11:51SPEAKER_2: So I'm interested to see what patterns emerge over the next few years.
- 1:11:54SPEAKER_0: Yeah, I'll add that I think mobile has been around, I think long enough now that we're starting to see sort of more mature patterns emerge and sort of similar to web.
- 1:12:06SPEAKER_0: I think a lot of folks when they're now exposed to mobile, have good guiding principles on how to build a mobile app or how to think about mobile architecture, whereas maybe five or 10 years ago, it was kind of like the wild west.
- 1:12:19SPEAKER_0: You could just do whatever you wanted to and you'd be sort of relatively okay.
- 1:12:22SPEAKER_0: But I think now if you're thinking about scaling a mobile product, thinking about architecture is a core part of how you think about building that product.
- 1:12:32SPEAKER_0: And so having more mature architectures, I think kind of where I imagine we'll go in the next five or so years, is just better guidance around how to think about mobile and mobile at scale.
- 1:12:44SPEAKER_1: And what advice would you give to mobile engineers who would like to grow?
- 1:12:47SPEAKER_1: Let's say a mid-level engineer who would really like to get to that senior potential, that staff level thing, and they're working on either iOS or Android, what would you suggest for them to keep growing professionally?
- 1:13:03SPEAKER_0: Maybe I'll start by saying that early in your career, I think a lot of your role is just being a good executor and just taking the tasks that you've been assigned and the projects that you're working on or that you're responsible for, and just shipping them on time and then doing a really good job with craft and quality.
- 1:13:24SPEAKER_0: That's sort of the foundational work that you're doing early on in your career.
- 1:13:29SPEAKER_0: I think what I found particularly helpful as you think about growing into more senior roles, is thinking more about problem finding and thinking about how the work that you're doing relates to the outcomes of the business, thinking about how you can move the needle on the objectives of the business and the work that you're doing can drive those outcomes.
- 1:13:51SPEAKER_0: So if you're thinking about that shift between early career to later career is keeping that top of mind and being sort of intentional about the projects that you work on, always asking why is this the project to do at this time?
- 1:14:08SPEAKER_0: I think that's a good guiding principle.
- 1:14:11SPEAKER_2: Yeah, I would agree with that.
- 1:14:13SPEAKER_2: I think a big distinction that we make between senior and staff at Notion is, are you just executing well versus are you moving business metrics?
- 1:14:23SPEAKER_2: And so your ability to identify those business metrics and then make an impact, I think makes a meaningful difference.
- 1:14:30SPEAKER_2: I would also say transitioning from executing well personally to helping others or providing frameworks or tools for others to make their jobs easier essentially.
- 1:14:40SPEAKER_2: So that could mean documentation or building out frameworks that are used by multiple people, that can take a variety of forms, even just pairing with other folks on the team or helping new people ramp up.
- 1:14:52SPEAKER_2: There are a lot of opportunities to work outside your current product or feature that you're working on.
- 1:14:58SPEAKER_2: Yeah, that's really [inaudible 01:15:01].
- 1:15:00SPEAKER_0: I think you still have to be a good executor on top of that.
- 1:15:03SPEAKER_2: Yeah, of course.
- 1:15:04SPEAKER_2: Yeah, so you're doing that in addition to execution.
- 1:15:07SPEAKER_1: And would you recommend on focusing on just the mobile technology or your mobile stack that you're doing?
- 1:15:12SPEAKER_1: Let's say you're doing Android, just focus on Android or to kind of branch out a little bit and dip your toes here and there as well?
- 1:15:20SPEAKER_2: Yeah, I think it can depend on your circumstances.
- 1:15:23SPEAKER_2: I do feel like going deeper in mobile is still a pathway to growing as an engineer.
- 1:15:29SPEAKER_2: Throughout this conversation, we kind of talked about a lot of depth that exists within mobile.
- 1:15:35SPEAKER_2: And if you're working on an app where you have an opportunity to do something like that where you can either go deep on something like performance or on these service layers like syncing transactions, there's a lot of complexity that still exists within mobile.
- 1:15:52SPEAKER_2: But I think there are other circumstances where you can expand to doing both, where you're basically working on mobile, but then maybe you also start to set up API endpoints or build out a basic version of the backend.
- 1:16:05SPEAKER_2: One of the first projects that I worked on at Notion was upgrading to Notion Plus on the mobile app, so we had to build out the backend for that.
- 1:16:15SPEAKER_2: So there are opportunities to work on projects that expand just beyond the scope of mobile.
- 1:16:22SPEAKER_1: Awesome.
- 1:16:22SPEAKER_1: Well, thank you.
- 1:16:23SPEAKER_1: So with this, let's just wrap up with rapid questions, if that's okay.
- 1:16:26SPEAKER_2: Sure.
- 1:16:27SPEAKER_1: And these are just really [inaudible 01:16:29].
- 1:16:28SPEAKER_1: So for the first one, I'll ask both of you and then I'll have the ones separate for the thing.
- 1:16:34SPEAKER_1: So rapid questions.
- 1:16:37SPEAKER_1: Do you use an AI coding tool for your day-to-day and if so, which one?
- 1:16:41SPEAKER_1: Austin?
- 1:16:42SPEAKER_2: Yeah.
- 1:16:43SPEAKER_2: We started using Cursor in Notion and I'm super excited about it.
- 1:16:47SPEAKER_2: It runs on top of Claude 3.5 Sonnet, which I think works really well.
- 1:16:53SPEAKER_0: And I think the differentiator really for Cursor is the interface of how you really think about AI completions.
- 1:17:01SPEAKER_0: There's a running joke at the org where you're just hitting tab the entire time to accept the suggestions and the reality is these tools will only get better.
- 1:17:10SPEAKER_0: So if you're not using an AI coding tool, consider it.
- 1:17:14SPEAKER_0: Play around with it, see if it works for you.
- 1:17:17SPEAKER_1: Yeah, and I'm impressed to hear because mobile is one of the areas where the tooling is just, it's a lot more sophisticated.
- 1:17:24SPEAKER_1: We know there's a lot of other IDs.
- 1:17:26SPEAKER_1: So the fact that you're using it, to me, is very encouraging and the fact that you have such positive experiences.
- 1:17:31SPEAKER_1: I think [inaudible 01:17:33] try it out if you're not already doing it.
- 1:17:36SPEAKER_1: Now, my next question is a bit more divisive.
- 1:17:39SPEAKER_1: So Austin, Swift or Objective-C and why?
- 1:17:44SPEAKER_2: Yeah.
- 1:17:45SPEAKER_2: I would definitely say Swift, no hesitation.
- 1:17:47SPEAKER_2: I've spent a long time working in Objective-C, and I would say Swift is what motivated me to continue as a mobile developer, to a large extent.
- 1:17:55SPEAKER_1: Oh, okay.
- 1:17:58SPEAKER_2: The community around it, I think, is really great.
- 1:18:01SPEAKER_2: And I guess just certain aspects of the language.
- 1:18:04SPEAKER_2: I feel like it's continually being improved.
- 1:18:06SPEAKER_2: Recently, the addition of stuff like Async/Await, I feel like there are a lot of exciting things around the language that keep me with Swift.
- 1:18:17SPEAKER_1: All right.
- 1:18:17SPEAKER_1: And Karn to you, Java or Kotlin?
- 1:18:20SPEAKER_1: I mean, that's not even a fair question, but I'm going to ask it anyway.
- 1:18:23SPEAKER_0: No, I think Kotlin is definitely the winner here.
- 1:18:27SPEAKER_0: To me, Kotlin feels like just a better version of Java.
- 1:18:30SPEAKER_0: I started programming by learning how to write Java, and so it has a special place in my heart, but it's like the languages are maturing now.
- 1:18:40SPEAKER_0: Kotlin just feels like it has so much of the syntactic sugar that just makes development a breeze.
- 1:18:47SPEAKER_0: And first-class primitives for things like concurrency and reactivity are just cherries on top of what Kotlin offers.
- 1:18:56SPEAKER_1: Great.
- 1:18:56SPEAKER_1: And finally, can you share a nonfiction book that you've recently read and you've enjoyed?
- 1:19:03SPEAKER_2: Yeah.
- 1:19:04SPEAKER_2: I recently read Skunk Works by Ben Rich, which is about the engineering team at Lockheed Martin.
- 1:19:11SPEAKER_2: During a period of very critical years, they worked on the SR-71 Blackbird, a lot of very, very complex projects.
- 1:19:21SPEAKER_2: And yeah, I feel like it's just very inspirational for engineering teams in general, a lot of very difficult problems to solve.
- 1:19:28SPEAKER_0: Yeah, that's a great book.
- 1:19:30SPEAKER_0: Highly recommend that one too.
- 1:19:31SPEAKER_0: But I've been recently rereading A Philosophy of Software Design by John Ousterhout.
- 1:19:37SPEAKER_0: And it's about managing complexity in software and the tricks that you can use to reframe some of your problems so that the problem itself is simpler to solve.
- 1:19:47SPEAKER_0: But yeah, highly recommend as well.
- 1:19:49SPEAKER_1: Awesome.
- 1:19:49SPEAKER_1: Well, thank you very much for being here and for sharing all these insights.
- 1:19:54SPEAKER_0: Thank you for having us.
- 1:19:55SPEAKER_2: Yeah, I appreciate it.
- 1:19:56SPEAKER_1: Thanks very much to Austin and Karn for sharing all these details and going deep into the specifics on mobile engineering at Notion.
- 1:20:02SPEAKER_1: If you enjoyed the podcast, please do subscribe in your favorite podcast platform and on YouTube.
- 1:20:07SPEAKER_1: And if you're interested in learning more about unique mobile engineering challenges, you can also check out my book, Building Mobile Apps at Scale, linked in the show notes below.
- 1:20:15SPEAKER_1: Thanks, and see you at the next one.