How Notion Builds Their iOS and Android Apps
Scores
how hard can it be to just render a list turns out it's quite complicated especially because Notions data model is very complicated one of the things that people really love about Notions data model is that if you have like a to-do block you can like convert it into a heading or you can convert a heading into a call out and a lot of these blocks are interchangeable and they're interchangeable in a way that sort of preserves the content in those blocks and on top of all of this is that notion is very reactive 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 so there's a lot of like zero to one work that we were doing to build out the realtime connectivity build out the reactive patterns and then all while keeping things fast and efficient notion is a productivity app and platform with more than 100 million users in today's episode we go to behind the scenes into the nitr details of how notion build its mobile apps noi'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 at the same time Notions mobile team is surprisingly all currently 11 Engineers even spit between IOS and Android for today's conversation I sat down with two long- tenured Engineers on the notion mobile team Austin lden is an iOS engineer and a tech lead manager for Notions mobile platform carab is a software engineer focused on Android 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 no's mobile text back approach to code reviews release and testing process and many more details on how the mobile team operate 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 if you enjoyed the show please subscribe to the podcast on any podcast platform and on YouTube so today we we have here with us from the notion team K sahab and Austin Lowden welcome to the podcast thank you for having us yeah thanks having us how is Notions engineering team different in some ways that you work compared to some of your your previous workplaces like you I'm I'm kind of asking like what what are some things that that feels like it's kind of a unique notion engineering culture maybe not as common elsewhere yeah one thing that I've haven't seen elsewhere is just this RFC process where uh the vast majority of product changes especially earlier on in Ocean's history um were kind of driven by Engineers through rfc's or requests for comments um and this meant that uh kind of end to end the product was being driven like you know through engineering essentially um and then those rfcs were shared companywide where you know anyone could comment on them you know leave feedback things like that I mean that is the request for comments um and that practice is has more or less continued today where whenever we want to introduce a new set of changes it's up to you you know as the engineer to write out the RFC and then tag every everyone that you feel like would have an opinion on this product change uh for them to review it um we kind of still see Engineers driving kind of the process from beginning to end for for a lot of futures um so yeah I think that's something that's fairly unique then obviously the the document is notion right and The Ting is notion a comment or notion yeah it's very helpful that everything is in notion so it just makes it easier to to navigate yeah whether that I mean I think that would be one major takeaway like you know 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 are very difficult to describe it is just immense because there's no question about you know where do you create tasks or where do you find a specific document um like 100% of is it it is in notion and uh yeah that just ends up saving a lot of time in the long run I think part of um you know like the engineering culture to like sort of like uh write these like rfc's or just documents and you know Austin mentioned that anyone can comment you know we mean anyone can comment for a long time there weren't a lot of like product Folks at notion oh um and you know you know folks from like different functions were sort of in these documents leaving feedback and helping us sort of iterate on sort of the thinking that we had or that we were sort of describing um and you know whether it's like senior leadership or you know engineering managers or like other engineers in like different functions or uh you know Park marketing uh growth you know everyone was sort of involved in these processes and I think that like part of what made some of like our our work very successful was that having this sort of high ownership High buyin environment for everyone to feel empowered to contribute at this level you know 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 this episode was brought to you by DX a platform that helps organizations measure and improve developer productivity the DX team includes notable researchers behind the Frameworks like Dev and space so they're constantly asked by leaders what metric should we use to measure developer productivity 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 devx 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 you can learn more about the DX score 4 and how is being used in companies like Dropbox Etsy versal and fiser at get dx.com cor4 again that's get dx.com slc4 I imagine there must be a lot of visibility in a sense that it's one things to have a document but people need to know about is it like advertised somewhere or just you search or like teams have it you know like in a wellknown places or how do you do that or use email I think there was um for us I think now our process is just like you know we use internal channels to to communicate this and you know if you're interested in like reviewing specs obviously we're like kind of at a at a stage now where it's not feasible for everyone to have an opinion on things um but now you know there's like internal channels for us to to communicate that like hey here's a new document that we want to get like internal chat channels exctly so we have a slack channel for example where all like 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 um we also have like rotations where uh engineers are kind of on the hook for reading all of the rfc's that come through or like within a particular domain and so um you know for a period of maybe like 6 months or so you might be on kind of like this RFC Review Committee that way we ensure that yeah essentially I think that's that's necessary to balance things out and that um you know for with mobile for example like we used to see a lot of rfc's where you know there wouldn't be a mobile section at all in the RFC you know like they would talk about the product but like there would be no mobile consider and so now it's helpful having somebody from the mobile team on that Review Committee that will you know surface that as an issue if it comes across yeah as team sort of scale I think it becomes important to have like a distinction between like the voices that are sort of important to the decision making and folks who are playing a sort of like uh supplementary role and I think like the Review Committee is like a one example of where you know we sort of outline these like nice boundaries around who's helping make decisions and sort of Drive decision making yeah but I like to hear how you just added in as it made sense right you going to started with a free form and then you slowly just like change it to make to make it work for you what are some unique things that the mobile team specifically does at at notion that are are like you know like part of the mobile engineering culture and I I think earlier you you told me there's like something around like you're you have meetings on Mondays yeah we do have we do have a Monday meeting um one thing that probably is unique uh at least I haven't seen before is we do like a weekly performance review where we look at all of our Topline performance metrics um like as a team like mobile app performance yeah mobile app performance specifically wow nice uh and yeah I think that just kind of came out of this time period where you know we really weren't happy with the performance of the mobile apps and so it's just kind of that mindset where you have to look at uh the metrics that you want to improve every week to actually get you yourself to make progress on them and so yeah for the last four years I would say we've been looking at you know our Topline mobile metrics uh specifically performance related metrics every week yeah the Monday meetings are are definitely like one of my favorites I think it's a good way to sort of start up the week and you know to sort of expand on how we think about meetings uh we have like two main meetings a week I think where you know a lot of companies do like daily standups or they have like sort of like recurring syns uh sort of multiple days of the week but I think notion especially on the mobile theme I think we're very much um like very mindful of like the time that Engineers have to do heads down work um you know there's like a lot of interruptions in the day and like one meeting at the wrong time slot is like kind sort of like throw off your entire day um and so we have these sort of like two main meetings the Monday syc is like a great way for us to like catch up review performance and then sort of chat about the things that are important to the team we have this like section called like the Tactical meeting uh which is sort of like these uh small items that we we want to chat about and we spend sort of like two or so minutes uh in sort of like a a group setting and then sometimes you know things discussions last longer than that and we move them async so it'll be like a slack thread somewhere about sort of a continuity around the sort of thing that we were discussing and then there's you know these Thursday sinks that we have which are sort of like projects in progress meetings where we review the work that's being done and how we're moving towards the sort of deliverables that we have for either the Sprint or for the Milestone or for the project as a whole um gives us also time to like reflect on some of the KT work that we're doing and manage like external dependencies that we need to uh sort of be aware of and then I think my favorite part is like demos uh we talked about performance a little bit but you know as Austin mentioned we weren't really happy with our performance at a certain point in time and so some of the things that we built in was um if you're ever looking at like a performance regression one of the things that you do is you demo your your investigation in these like sort of Thursday sinks oh nice and that's a good way for us I think like number one to like share knowledge on like how to do these investigations because you know doing performance investigations are kind of hard um and to spread the knowledge and have people sort of ramp up on performance investigations is like kind of like important and so these demos are like a great way to do that and there's also like sort of design demos and sort of like future looking things which makes sort of like the Thursday meetings super exciting but you you mentioned but you also told me earlier that you don't do Sprint planning how does that add up yeah we don't really formally do Sprint planning but we do uh have kind of higher level Sprint commitments so we do work on like these two we cycles and at the beginning of the two weeks you basically say you know what do I want to get done over the next two weeks and so this is much much higher than the task level um and usually only is like you know two or three bullet points enough to describe like I want to build this section of this feature or eventually later on it gets to the point where of like I want to ship my feature to Dev or you know ship it to production launch the experiment um and then you know after the two weeks goes by we'll go through and people will talk about like you know were they actually able to kind of make progress in their Sprint commitments you know if they weren't able to make it you know like what do we not account for you know uh so and I think that Cadence works out pretty nicely so would you mind sharing some context on on notion in terms of the number of users you have how how big we can imagine this app to be in complexity users of that kind of stuff um yeah so uh we recently crossed 100 million users um and we have around tens of millions of users on mobile um about half of new notion workspaces are created on mobile uh so it's a pretty substantial top of funnel for notion generally um you know a lot of users will start on mobile and then potentially uh move to using it across multiple devices like on desktop web um in terms of the team um mobile team has 11 engineers and that's roughly split between IOS and Android notion all together has around uh 600 employees wow so that mobile team is not really big is is it a more senior team is it a is it a mix of juniori how how can we imagine that yeah so in general Notions started out pretty senior heavy I would say um we wanted to look for folks that were kind of around five plus years of experience to start um and now I would say we're evening out a bit more um we've started an internship program recently and a lot of interns have converted to full-time uh so we're getting a bit more of a balance but um initially yeah notion overall was quite senior heavy when did notion first ever have a mobile application and I understand this was before you joined the company right yeah I think it was before both of us joined the company the original notion mobile apps I think we're around 2017 where we kind of like published the first versions of the apps um and they didn't really see a a lot of active development until around 2019 when we started investing a little bit more in the mobile experiences and for a long time it was just like a small rapper on like the what is effectively like the the browser app can we talk about that what was this first version of of the app what technology did it use and and you know how was this wrap around was it a VB web view wrapper or something else yeah so the initial app used Cordova um so it was effectively just a a wrapper around uh our mobile web app um but uh for a couple of you know OS specific things we were able to use Cordova to hook into that um and then later on we we moved from Cordova to react native um although I wouldn't necessarily consider this react native in the traditional sense it just used react native uh purely for those kind of like OS hooks so for example if we wanted to make the app like vibrate or something like that you know you could use uh like the react native API for it um but it was predominantly using just a single web view component that was rendering uh you know our our mobile web view essentially and 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 of what it is and you know why not just you know use the traditional web view like what advantages did it give at the time yeah so Cordova provides a way of writing kind of crossplatform code um to where you don't actually have to write native Swift or you know Objective C cotland Java um and instead you can uh just kind of write plain javascripts and have those hook into uh you know like native apis essentially so it provides kind of a lightweight way of using a you know web view predominantly for your app uh but then like you know using um uh some of the OS capabilities like if you wanted to force the phone into landscape or you know make it vibrate things like that so notion had this this app uh it was sounded like a somewhat more app back in 2017 and then the two of you joined in 2019 and you you decided all right let's do something more more native how did this happen and and how did you even make this decision because that's a pretty big decision to say we're going from some you know HTML rapper pretty basic stuff we can use a lot of our our web logic to starting from what sounds fresh yeah I I mean you bring up a good point which is that like we already had a bunch of like existing work done to make the mobile apps sort of like relatively uh good for the notion experience and if you've ever used notion you know that it's like a relatively complex product it's not just like you know text blocks or todos there's you know Collections and embeds which kind of make it a very complex offering and so you know around this time uh sort of like 2017 2018 um if you look back at that time and and you ask users like how they thought about the mobile apps I think one common complaint you'd probably hear is that the performance wasn't that great um and if you think of using notion in the way that most people use notion so if you're like especially on your 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 um and like you know put in new uh grocery items or you're on the go and you want to take uh or on the go to like work and you want to take down some notes uh just something to remember having a sort of poor experience isn't ideal um and it makes it sort of frustrating for users to to continue to use a product so one thing that we wanted to do is kind of address this like performance problem and a lot of our sort of decision to go to Native uh was premeditated on this idea that like if we moved things to Native it would get faster for us and you know I remember I think it was like 2021 sort of like the end of the year we'd sort of come out of this offsite uh with what we felt like was a sort of crisp vision statement on how we thought we wanted the mobile apps to appear and what we at the time is like everything except the editor would be native and that's kind of like was our guiding principle going into like making things native and over time you know we were like building out these these tabs uh you know the Home tab the Inbox and search tabs which are kind of the prominent um entry points into the different parts of notion and we started there and we said if we slowly convert these to Native we can see the performance uh benefits and it was also like a you know a good way for us to like stress test native we'd start small build incrementally uh and then you know sort of like verify our findings and see if we were actually making the apps better and you know what we found was that they were moving to Native made things better for us 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 mobile Engineers come like oh let's do Native because it'll be more performant but this was around at the time right in 20 19 or 2020 let's say company like coinbase said we are moving away from native because we think react native is is performant enough how did you you know what did you look at at performance 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 yeah I I think it really comes down to um like app start time and so for us like a metric that we look at pretty closely um is something we call Initial home render which is just the time it takes from you to tap on the app icon to no to appear and all of your items in the Home tab uh to to be visible so we knew that there was effectively a ceiling as to how fast we could make it if we kept uh the web layer around essentially um and you know the reason why that's slow is because we have to boot up a web view uh and then we have to kind of load our entire appjs bundle um I think there are ways that this could be done a little bit faster um you know if you've modularized to the extent where you're not really loading a large bundle but we're effective L loading all of notion when we launch the app um which means uh you know our our launch times were a second and a half or two seconds which is you know fairly slow for for industry standard and so we felt like we would never really get to the point of like an industry standard uh mobile app without kind of substantially uh you know moving the needle um for things like react native or or you know like alternative Technologies like that um I think we still didn't we weren't convinced that we could go as far as we wanted to go without being purely native um I think there's still kind of a ceiling there with those types of Technologies um but that wasn't uh you know it didn't really meet where we wanted to go with it I mean clearly there's a ciling for every technology but do I sense correctly that what you're saying is that by going native you can keep it at the the bare minimum right you do have the option of cutting back everything you know you have to give up a bunch of stuff to have a the the boot up you know with the hello world application but you can actually control and tweak and make those tradeoffs yourself right yeah I think that's kind of what we were thinking would be like the biggest benefits of moving to Native is that we'd have more granular control on like what exactly our startup path looked like and if you think about like web Technologies or you know just like react native or Cova for example they're usually just these like shim layers on top of the OS um 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 like startup performance yeah especially with you know notion is competing against a lot of personal apps like you know we compete against like Apple notes and Google keep which are all fully native and so you know for for certain companies you know like coinbase you mentioned uh it might make sense for them to be able to use something like react native um but you know for our Market I feel like you know if we're competing against Apple notes we have to be you know near to as fast as Apple notes otherwise we don't really feel like it's feasible yeah or even try to be faster if you can obviously but yeah that makes a lot lot of sense and I think it's a good reminder right of like there's no Universal things right right as you said it depends on who you're competing against what your priorities are but one thing that is a bit tricky to do with Native development or one of the push back that most companies have these days is well it takes a larger team how big was the team when you started this project you told you told me it's like 10 11 people but back when you started how many of you were there was it just two of you was it more people um I think it was four people total at the time uh it was like two iOS two Android um and yeah like a relatively small team to start but over the course of the projects that we were doing to kind of like move things to Native we were also starting to like scale the teams so we didn't kind of like do it with four people the entire time um it slowly grew um and like more people uh became sort of like instrumental to different parts of the project and can we talk about how this I guess rewrite happened we're even thinking it of it as a rewrite or was it a new project or because sounds like you kind of you know you had something but you kind of slowly moved over to a point where now it's all Native or almost all Native how did you even think about this yeah that's right um we were trying to make it incremental in some form um and so we were're looking for like what is the largest like meaning or the smallest meaningful chunk that we could move to Native um and for us that was the Home tab um so that's the first thing that you launch into and so you know I mentioned earlier like initial home render that's the most like uh prominent metric in terms of like perceived performance of the app um so we started with this Home tab slice uh and then later on we were able to move to the other tabs so um after that we shipped search natively and then we shipped uh inbox natively um but uh yeah hom tab was kind of the major part of the rewrite because at that point uh we had no native code at all it was purely just the web View and so that meant that we had to uh like start from scratch effectively um like I remember at the time we we didn't have a way of making authenticated like Network requests natively so we literally had to write like you know the network layer uh like all of all of the service layers that were kind of required to run notion um to start um so that was kind of what was seen as a rewrite for us because basically nothing existed at the time um but uh search and inbox were a little bit easier because we were able to build out the service layer in the meantime yeah and I I think like it's pretty common in the industry to like hear like horror stories about um like full rewrites taking like multiple years and I think like that's like a a bit of like a failure mode that we wanted to like guard ourselves against and make sure that we were shipping something that um we could complete in a reasonable time frame and then also just like vet whether the approach that we were taking was going to work like it was entirely possible that we like move things to Native and it like performance got worse or startup got worse um or like it just wasn't compatible in the way that we wanted it to uh to work so yeah I think like that was a common failure mode that we wanted to like guard against and how how long did this whole project take so like in 2019 you said like all right let's start with the Home tab and then later you added search and some of the other things at at what point did you get to the point where you're either the whole thing was native or or most of the things that kind of matters were were Native in your mind right yeah so the Home tab itself took about 9ine months uh and so we started in 2021 um we wanted to ship sorry oh God so you start to make a plan like when you joined like all right we're scheming we'll we'll we'll try to make something yeah so we knew like because of this incremental approach Like Home tab once once that was shipped we were able to take a step back and then you know move to these other tabs later on um end to end that that whole process has basically taken four years but we've shipped other things in the meantime um the Home tab project itself was the only part where uh basically the entire team was working on it and we could do nothing else until it shipped uh effectively like it was blocking everything else on mobile and and just to explain what the Home tab is because I have I have my notion app here open like can you can you tell me like you know why it was it sounded like it's a big project but why was it so complex you know I just look at it here and obviously I I don't have my inspector right on so I don't see the elements but I do see recent documents I do see a lot of quick notes I do see task lists Etc so the hom tab for for folks who don't have context into like what Notions hom tab looks like is if you've ever used notion there's a bit of a sidebar on the web experience sort of adjacent to the editor and the sidebar is uh sort of like your navigation Hub it has all the sections for your favorite Pages your shared Pages team spaces if you're part of like uh you know uh like larger workspaces and it's kind of like your central hub for all the information that you have in your particular workspace so on mobile that's kind of like the Home tab it's that sliver of the notion experience it's your entry point into the the rest of the your like work and your documents and so you know the the obvious thing here is like it's it's just a list like how hard can it be to just render a list um turns out it's quite complicated um especially because Notions data model is very complicated um one of the the things that people really love about Notions data model is that if you have like a to-do block you can like convert into a heading or you can convert a heading into a call out and a lot of these like sort of blocks are like interchangeable and they're interchangeable in a way that sort of preserves the content in those blocks now this extends to other things like titles so you a common example is like you have like a title with a mention for like today or you have a mention for like a particular person and in other cases you might have a mention to another page and so there's this sort of like recursive structure that we're we're starting to build out and on top of all of this is that notion is very reactive 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 so part of what we need to to build was not only just like list rendering but also the reactivity around all the rows and the the sort of content that you had in um in your sort of notion hom tab so there's a lot of like zero to one work that we were doing to build out the real-time conductivity build out the reactive patterns and then all while sort of keeping things fast and and efficient so I know it was like it was going from what was effectively nothing to rebuilding notion sidebar and navigation sort of PR so so you built a sidebar you built navigation sounds like you built like the the real time processing of of events updating of the UI did you do some like UI elements or like some some starting to some internal design system or that kind of stuff as well yeah I think like you know part of like building out these home like the sort of like these tabs and moving to Native we had to be like very intentional about what we wanted to like scope as part of the work that we were doing because it could easily blow up into like a like a very large project and you can think of like systems as being one of those things that are like nice to have um but as a your product scales it's like becomes more and more important to ensure sort of a consistent experience um and you know the design system is something that we only like built out in like the last couple years when we first started we were in kind of like a an MVP sort of mode um and so a lot of the stuff that we built out was just very Bare Bones we were like can we match the the specs that we have that's good enough for us yeah to give another example of uh the complexity um so notion is local first in some sense and that you know when you make edits to a document we want those to be preserved and then sync later so there's kind of a similar effect on hom tab as well so like one action that you can do is favor a page um and in most applications you kind of expect this to be pretty straightforward where you know you tap favorit and then it makes some API requests with like the page that you want to favorite um but in notion uh this is considered a transaction and a transaction is like any modification into a piece of data so if you are you know typing in a page you know you're you're transforming kind of that text from one state to another state um so favoring is just an example of another transaction that's possible um so instead of making you know an API request uh for this we needed to build out this whole layer of of syncing transactions so when you favored a page you know we'll create that you know favorite transaction structure uh and then we write it to sqlite and then that's periodically flushed uh so you were already building your local data model right and and I'm assuming you know later you would use this in other places as well obviously yep okay yeah yeah these are things right like I think even I'm sure non-technical people don't always appreciate it and they're asking you know why does it take so long for engineering but even as an engineer that was a bit surprising to me 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 what about the editor like if if I think of notion if if I would have to make an educated guess based on what is the most complex part of this application I would just burd out it must be the editor because you can add all these things add all these blocks there's tables there's there's all sorts of text manipulation I'm sure there's like rendering of fonts there scrolling there's all these these hard problems in uh in software engineering I mean if if you like build something rendering how does that either compare to the homepage or or is it actually easy easier or is it is it harder and you know like where does that fit into the project to me like it seems like it's just a big part of what you must have built yeah definitely I think the editor uh the reason why we took this approach of sequencing it home tab search tab then inbox and then saving the editor for last uh is because it is the most complex part uh 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 um so like as part of the in project for example um we're beginning to render certain Rich Text blocks natively so that means uh like blocks that have like code annotations or or like at mentions things like that all of these elements that are part of our text editor normally um so we're already now I would say at the phase where uh there are certain chunks of the editor that we could just kind of do natively um but we need to figure out like where the right user experience would be uh to to you know handle them more complicated parts so notion supports these things called collections uh which are essentially like mini databases inside of a page uh so doing that would kind of be a whole another uh long project um we also have a lot of embeds so like you can embed uh you know figma designs for example within a ocean page and you know scrolling in a native view with multiple web views embedded uh would be quite complex uh so that's another problem that we're you know uh we'll need to deal with at some point but um yeah that's just a really interesting thing to think about and I'm glad you brought it up because I think it's just not obvious from the outside right that it is this is a game of trade-offs you know like you have a small engineering team and for example now I start to understand why you start with the the biggest kind of the most frustrating Parts the app startup the Home tab so I think this is a really interesting takeaway for anyone who not even in your domain necessarily but if you're embarking on a difficult technical challenge you're kind of leaving the yeah as an engineer I 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 yeah I think it was also helpful that part of what made that decision a little bit easier was that we knew that the like booting up the web app was the slowest part but once we had the web app booted it was like relatively okay we could get things going and scrolling was good um but it was that initial sort of Chunk that was the most difficult for for users well I'm assuming that you know 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 prefet those kind of things yeah and that's exactly what we do is while you load the Home tab in the background we're loading the the sort of like web app so that by the time you click into the the page that you want to go to it's it's already ready for you a super now you're a small mobile team and like there will be some people listening for 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 on a day-to-day basis both in terms of engineering teams and and not engineering teams what does your typical you know week look like for for for a more typical mobile engineer at Ocean yeah we work pretty closely with other teams um I think uh like our sister team would be probably a web infrastructure essentially because they're also a platform team um although you know we're kind of in the Middle with we support both platform and features um so generally this plays out through planning where uh you know other teams are are planning to take on a particular uh new feature that you know needs a mobile experience and so then we try to figure out uh should these things sips ships separately yeah I think we're primarily like a we sort of function as consultants on these on these teams um just because our bandwidth is a little bit more constrained uh and so our job is to sort of help out where we can and I think it's helpful for us uh because we've established a bit of like a good ownership model so a lot of web teams are still responsible for their surfaces um specifically like the web ones that appear on either mobile web or mobile native and so we'll continue to provide Consulting and make sure that you know folks are on top of um building out features that are compatible with like sort of these different form factors um but then there's you know these like native surfaces that we've converted and spent a lot of time building um where we take more of sort sort of like a a lead and and we'll take the requirements from other teams and figure out how we can best port them into our our native infrastructure and build the sort of relevant things that are necessary to carry out those requirements interesting I don't often hear mobile as a consultant setup it does make sense right but I I think it just comes to show that that every team and every company is different there's no one size fits all I am interested to hear a little bit about your 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 or other engineering approaches 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 I think uh 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 uh and this sort of our approach for a very long time is let's build things together and build them sort of like simultaneously this would be super helpful because U because we were a small team a lot of us would be dring our own individual projects and collaboration was kind of limited to um just like the platform that you were working on and so to kind of make things a little bit easier and to um build on both platforms at the same time uh we kind of did these in like pairs uh or at least specifically like the smaller projects that we worked on these like larger projects the Home tab and inbox usually had like multiple people working on it but in terms of like our collaboration at least between the platform teams um like IOS and Android it was you know we tried to do things as much as possible together yeah it also say the the structure of the apps um we tried to kind of mirror them as closely as we could uh because we were doing this rewrite kind of in tandem uh like the the services and the modules that we created uh are kind of a one for one match on iOS to Android so um like the the service that interacts with SQL lights or the service that like syncs our transactions um you can go in the iOS codebase and kind of find roughly as similar file structure as you would see in the Android codebase um since these were all kind of plan together C can we talk about the tech stack specifically the languages Technologies Frameworks that you're using in IOS and Android and maybe for for shared if there's anything shared yeah I think Austin touched on sort of like a uh an important part here is that we try to do things a lot like very similarly between the two platforms despite having different languages so like our persistence lay is like SQL light um seems sort of like ubiquitous across the industry to use some version of SQL light somewhere in your applications you're saying you're not using core data on there's like small tidbits where we're using these like sort of things but our primary use cases are like SQL light for our persistence layer obviously we're like a sort of cotlin Swift um at least on the mobile mobile side um and then you know web views power the sort of like hybrid portions of the apps um yeah yeah on on iOS like K mentioned we're using Swift exclusively except for the parts that are in web view which are all in typescript um we rely pretty heavily on combine and uh like flows and cotlin because of the reactivity of notion um you could you just explain what what those Frameworks do yeah sure so um it's really a way of working with streams of data uh so if you've ever worked with like RX you know there's RX Java things like that reactive pipelines so it kind of puts you in this mindset of instead of working uh with you know a static set of data that you are working with a stream that is expected to change uh so you know an example that Carr 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 like as you're looking you know at Home tab and so kind of handles rendering and things like that or or is a way of piping data to the uh view layer um that uh is is reactive yeah I think also in the The View layer um where like Chacos Swift UI and we're like pretty early adopters when we first started some of our migrations to Native uh we picked Jeet back andos and Swift UI as um sort of the bets that we had oh but you made that bet early at least with swift UI it was very new right same with compose jetpack no both both of them were like relatively early and um you know whether that was the right call I think is just like we have a bit of like survivorship bias I guess because it sort of worked out for us but you know it was sort of like pretty rough in sometimes um sort of like building out with these like pre 1.0 Frameworks um especially for like what is effectively like the most critical parts of your app um and there's like you know these like examples of like things that we would to like circumvent uh like issues that we were seeing so one of the things was like compos was really slow at the start like performance wasn't a big part of like like the libraries um or sort of like the library designs um or like what they wanted to like prioritize and so we'd see these like esoteric bugs show up um like scroll performance would be like really bad um oh in like certain cases and we would spend these like in time doing these investigations and one of the things that we found was that materializing the click handlers on these like rows was like really slow as you were scrolling and so we do these like fun hacks like disable the click handlers as you were scrolling and then once you stop scrolling we would like reattach the click handlers just so we can get those like marginal improvements in performance and work around these like weird issues of like a pre 1.0 framework but knowing what you know know now would you you know like that compose for example had the these issues would you still choose it and and go around and fix it or or would you just go with something that's kind of boring not not as functional but but kind of more stable because like you know like this is really interesting because when you don't know you just go with go with the punches right you kind of do it but would you change it I think on Android probably not I think despite these challenges I think we I think we made the right bet in hindsight um I think most of sort of like Android development at least modern development is moving towards compos in in cotlin and so I think being early adopters helped us not as only as Engineers ramp up on this new framework but it helped us sort of change the way we thought about um building UI like Jaan compos and Swift UI are like declarative UI Frameworks um and they you know you sort of build UI a little bit differently than you would um and and sort of like a good way to at least to solidify my thinking around this is that like if you ask someone to build a list in cotlin and you wanted them to or sort of like an on Android and you wanted them to like use like the old XML Style versus the new jetpack andos style one of them is way easier to do and I think that that is just like an apt example of how we thought about sort of moving to compose I don't know Austin what do you think about Swift yeah I I would say that we're in a similar position with swift where it feels like the iOS community is all moving towards Swift UI you know this is where the documentation is all being written you know blog posts this is what Apple was talking about throughout WWDC and they are making some changes to UI kit um but you know Swift UI seems to be kind of their predominant area of focus so it seems like developers are kind of stuck in this Middle Ground where like they're worried about kind of these risks associated with swift UI uh but you know this is where the community seems to be heading and so I think there's almost a cost to not choosing it at that point because eventually you know you will sign yourself up kind of for a rewrite later uh you know down the line um but yeah I would also say that there were there were some pain points you know we had to work around some some odd bugs with swift UI um 90% of the views I would say were very easy and straightforward to write and I think that's where there's kind of a major developer velocity Improvement um with these these Frameworks and similar with jetpack and pose um but then there's that 10% of views where you know the API doesn't exist yet or there's just some odd with it particular that that may incur quite a bit of cost but overall I would still say that I would make the same decision again to go with swift UI but it's it's encouraging because I I think it is good you know right when you can move with the industry and looking back say like you know what it was the right call because it sounds like if you chose the existing stuff you know UI kit or or or just you know like xmls you would be pushing A migration ahead of you at one point which will be painful and you know it's a more mature system it's a good reflection I have to ask you code reviews uh do you do code reviews uh do you do cross iOS Android code reviews H how do you do it because you're such a small team it's it's it's very unique right most most mobile teams will when they're bigger it's kind of pretty straightforward Android Engineers review Androids code iOS iOS Etc there's no cross pollination what do you do though yeah we'd occasionally do crossplatform code reviews um if people are working on uh kind of the same feature you know you're in this 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 uh are kind of in sync with you know your iOS or Android counterpart like throughout that process um but otherwise I would say maybe 80 90% of the time um code reviews are done within the platform um but yeah I would say we follow a fairly Standard Process um although I one thing I've noticed at notion is that we are quite quick on code reviews like we try to keep that timeline from like a a PR goes up to it being reviewed um uh to be very fast um because just that kind of unblocks The Next Step so does this mean that people prioritize to kind of stop what they're doing or you know interrupt their own flow to unblock some I mean obviously not not as a guideline but like you know there's a tradear right between like all right I'm focused on myself versus I'm going to help this person out for like a few minutes yeah I think generally people would glance at it right away and if it's short then maybe they'll they'll like kind of stop what they're doing um for longer PRS though I would say we try to take about a day or so SLA um you know that tends to speed up the whole process uh We've also started using a tool called graphite as well um so people are beginning to you know stack PRS and and that helps as well you know like we actually have a deep dive on stack diffs and on on graphite into pragmatic engineer so we we'll link it into the the show notes below that that is awesome to hear yeah I mean I I think that helps because it puts a little bit less pressure on on reviewers to kind of get it out right away um and yeah graphite is is great in that you know you can pretty easily switch between uh parts of the stack uh to to update like that specific part um one thing I'll add is that I think the mobile team you know because it was originally like a little bit senior I think folks would move pretty quickly on on the diffs and um I think that was like helpful because you don't need to ramp up as much and then the other real benefit was that because we were a small team almost everybody was reviewing PRS and by sort of like uh proxy you would learn a lot about the rest of the code base because you were just like so heavily involved in like the code review process and that kind of like snowballed and like over time it would just become easier and easier to review PRS because you had more and more context um and well you know hopefully we'll we'll see that continue to happen as the you know as the teams grow but um I think that's kind of like what contribute to things moving a little bit quickly as well and in terms of engering practices that also make Cod reviews easier how what is your take on automated tests linting static analysis because you know like 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 you know like the C if if the code review checks all those automated tests it's probably going to be okay like what balance have you chosen there yeah I would say earlier on kind of throughout this rewrite um we weren't very upfront about writing tests for uh uh like things that we didn't feel like were very critical I guess um we would try to write tests for uh like service layer things so you know syncing transactions stuff like that that we felt like absolutely could not break um now I think I'm trying to get us to a point where um all of our modules that uh like their public API or their public uh methods that they expose are tested um but that's kind of a long-term idealistic goal uh but making slow progress towards that yeah I think we were definitely like picking and choosing what we thought was going to work for us in terms of like testing and and and builds and and you mention that like you know the tradeoff is that over time your bills just become more complicated and you know where typescript shop like at notion as a whole and you know type tracking on notion just takes a long time because it's like a very big code base and there's like you know dedicated efforts to make sure that those checks are efficient both on like the typescript layer and you know for us in the mobile teams is you know code reviews are just one part of developer velocity the other part is making sure that you're changes are merging as quickly as possible because the longer diffs stay open the more likely there is for merge merge conflict and you know the more likely that things just sort of drift so we want to like sort of close the gap on on those sorts of like preventable um you know developer velocity issues yeah 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 how long does it take to compile the the IOS and Android app from a clean State clean I would say maybe about 45 seconds um which is quite fast you know our is still relatively small yeah yeah it's it's still relatively small um you know and and we've come both K and I have come from companies where the clean build are probably like two two minutes to even five minutes um but even that I feel like we're kind of trying to get ahead of it by modularizing to the extent that we do um so we kind of take this approach where uh like every single service so like you know our Network layer our transaction sync layer those are all modules that can be built independently and compile time for that is you know a second 2 seconds and so if you're working that's awesome yeah um if you're working in a particular area of the code base uh then you can just kind of switch your target to that module and build it um and you know potentially that would set us up uh to migrate to something like basil or or buck if we wanted to in the future yeah I think folks underestimate like how important it is to have like fast build times um you know you hear stories of folks who are like I hit build on xcode or enter studio and then I like I left to go get coffee or something because it takes so long um and you know rapid iteration Cycles are like a key part of like I think what engineering culture at notion is is about uh so we're like very intentional about making sure that we don't sort of regress build performance oh yeah another thing that we're we're kind of putting ourselves in position to do is like 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 like all of its dependencies I I've seen um if you've heard of Point free Brandon Williams Steven CIS they run kind of a iOS um like video series but um they've talked about this approach where they've kind of carved out specific sets of the app and so they can you know just build a a subset of the app like if you're just working on the Home tab for example you know you can build that feature and all of its dependencies kind of in a single View and that's another strategy of just you know speeding up build Times by cutting out all the unnecessary modules so you mentioned modules can you give me a sense how many modules the current notion app has and and when did you introduce these modules and because it's a lot of work to introduce Mo modularization and my native approach would be you sold me oh the clean bill takes 45 seconds ah we can probably hold that off until later but clearly you didn't do that yeah so the IOS app has about a 100 different modules currently and what it means to be a module it's it's pretty lightweight um really you know we're just defining modules through our package. Swift file and so um being a module essentially just means it has its own folder we explicitly specify its dependencies like what are you know what other modules it depends on um and then you know because it's specified in this way and package. Swift it can be built independently um and we've kind of taken this approach where every unit is either like a feature or a service or a model and kind of falls into one of these categories and you said uh just clicking what you said so you said it's either a module a feature or a service I understand module what what do you mean by feature or service sorry to clarify um a our modules all of them kind of fall into these categories so a module could be a feature or a service or a model I think that might have been yeah oh I understand so this is like the three categories of what a module can be yeah um we also have uh like helpers and UI there are a couple of different categories yeah generally its category kind of helps us understand where it might live in the dependency tree 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 um but things like features they're expected to have quite a few dependencies so like they'll depend on services and models and other things and this way you know if you're this is kind of what helps keep the the build time for specific modules very low um because if you want to build a service you know that like a service is generally only going to depend on maybe some helpers maybe some models um but nothing higher than that in the dependency tree yeah on the ENT side I think we're trailing a little bit I think we're at like 50 or so modules and I think what what you asked earlier was like how are we thinking about creating these modules and I think for a long time especially doing like the early development features um we were saying that like oh every new feature would potentially have its own module um and as we built out more features we would like split things out uh a bit more intentionally um but yeah as Austin mentioned I think it's like kind of lightweight we we sort of do it when we think it's the right time to do it and in Android do you also have this categorization of model service feature helper yeah I think we try to keep it consistent because it's just helpful to understand the code base um both as like an Android engineer looking at iOS code or an iOS engineer looking at Android code it's very helpful to have like a similar structure despite having different languages and for us I think it's like the best thing we can do is sort of keep the the Gap as close as possible um for folks kind of like pivoting through the different different Stacks yeah one other thing it helps with is um like kind of you can you can do migrations on a module by module basis so for example um Apple just Rel or the Swift team just released uh strict concurrency um and so this is like a flag that you can enable to add extra compile time checks for whether or not you know you're kind of using their concurrency tools in the correct way and this can be enabled on a module by module basis so it means that we can kind of incrementally go throughout the codebase and turn it on um which makes these types of migrations so much more easier than they would be otherwise it's interesting because I I feel there's it's not a one-on-one mapping but there's a little bit of similarities between microservices on the back end or Services depending on how you call it and and modules on on on mobile obviously not not one-on-one but both require planning both have upsid both have upkeep but both can you know if you do it well it can it can just you know make you go faster as a team so how do you release build and release the app because this is something again as as a mobile engineer I think we know how painful it can be but you know as non-mobile you just see like notion app appears every week or every two weeks uh on in in the App Store what goes behind the scenes of going into that release there's going to be some sort of you know builds QA some sort of other Gates what steps does it take to to get it out there and how often do you push it to the App Store Aus do you want to take this or oh sure sure yeah um yeah so we release the apps uh once a week um and we cut a build on Wednesday night um this we start the release then on Friday um but these are all like a progressive rollout um so it sounds kind of odd to release on a Friday um but what we release on Friday is just out to 1% typically so that's actually like kind of the least risky part of the release um then it kind of picks up by Monday we have uh maybe around 20% or so and then kind of it increases throughout the rest of the week um one very unique part about notion is that uh because we have this hybrid you know native and web client uh we're bundling a version of our appjs uh when we cut that build on Wednesday that is continuously upgraded so uh one you're running notion you know just using it normally um we're checking in the background every once in a while like is there a new version of the web client and then it will download and update that so our our web app is continuously deployed essentially so uh you know at any given time basically you could have ative version that we know your web app is at least as new as that Wednesday cut uh but then potentially you could have a web version that's a little bit newer you know at least a week newer um so that introduces a set of challenges um you know and the differences between those two things uh that we've tried to have engineer around but um yeah that that's kind of the general release process um we also have a public beta uh on test flight and the play store that releases uh nightly so um anyone's able to join and we generally uh you know enable sets of new features and we're looking at kind of Crash logs from from those betas a bit more closely so you have a nightly public beta so if people who join a public beta they will get the nightly cut build wow that's that's Cutting Edge uh most companies would do that internally or a lot of companies do it internally but few would do it externally that's great to hear yeah yeah I think we felt that not having it nightly like was not giving us enough signal um I guess uh to say that in another way um if we cut once a if we're already releasing once a week if we were to release a test flight like a public build earlier uh then we would only have you know maybe two or three days of signal and you know kind of depends on the adoption rate of the build so uh yeah being being nightly helps yeah we can you know I think some of the benefits of it is also just like it gives is a bit more granular information on what's happening between releases um as you can imagine that if you're releasing once a week there's a bunch of commits going into your code and then that is being rolled out to users and so you effectively have like a a large chunk of commits going into a single release and if something regresses now you have to sort of like work backwards from that uh that sort of like entire chunk and figure out where things are having bills go out nightly gives us smaller diffs that sort of rolling out and helps us detect issues a bit bit sooner in the in the sort of like release process and what is your usage of feature Flags because classic tool in in Native mobile because you can only release once a week or few places do more frequently you you could but there's drawbacks is you just wrap stuff into feature Flags you do stage roll outs onto them how is your thinking around that or how is your you know like practices around that yeah I think it's gone pretty common in the industry to just like heavily rely on feature Flags I think gon days of like six Monon release Cycles where you can like vet and build your features in one one chunk and then you know be relatively confident that you're shipping things like that work um with mobile releases going out every week and and like nightly for the you know the betas it means that there's a lot more sort of like things that can go wrong and feature Flags help us guard against those those issues I think at notion we use them in in a couple different ways but i' would say primarily we use them to First gate features that are going out or the ones that are being like actively developed uh because you know folks are merging PRS their stuff is sort of like being developed behind the scenes and then there's the sort of second type of feature flag which is something is being rolled out maybe in a staggered roll out sort of like you know 10% 50 whatever um but then we find out that something is like going horribly wrong like there's a particular crash mode that's causing data loss for example um that's a kind of like a really bad scenario and we want to get ahead of that um and you know because we're doing these like weekly releases we can't have things linger like that in production for that long and so future fact has become sort of like a very important mechanism to control um these sort of failure modes C can you give a sense of like at any given point in time like what the number of pacher flags might be roughly are we talking about in tens or hundreds or or even more uh across the the notion app of you know active things that are are being potentially flagged or or or the potential to even turn them off if things were wrong yeah that would be in the hundreds I would say um I I think it's just a general practice if you're uh you know developing something to wrap it in in a feature flag and that's probably one of the first things that people generally do when starting a new project is you know they'll set up the experiment um set up the feature flag and then uh like begin development like within that um so uh yeah it just seems to be generally good practice um we have a Dev environment uh so we haven't really touched on deploys yet um we have a Dev environment that uh all of the employees are using and so generally we enable like quite a few feature Flags in that environment that are not enabled in production um and then we have a staging environment that is tested by QA that mirrors production as closely as possible um so so so Ju Just to just to make it clear would you mind like clarifying like how many environments do you have and like what they're called yeah so I guess we have four environments uh although there are really three important ones first would be local and that's just kind of what you're developing on locally um the next one would be development and so development is what all of the notion employees use so whether you're on the mobile apps or on the desktop app um there is a particular environment that hosts kind of our notion internal workspace uh that all of employees are kind of working Within um that's like kind of where we get all the dog fed feedback from um then there is uh and that is deployed continuously throughout the day so like very uh frequently um then there's the staging environment uh that QA tests and that is tested nightly and so they go through kind of a variety of flows basically making sure that the core experiences are working throughout the app um and then there's production uh and so as we go from De to staging to production we try to catch kind of various things throughout the process I would say the vast majority of things are caught in Dev by employees um because you know notion employees are using notion to build notion uh so heavily uh a lot of things are caught in this Dev environment um and then I would say probably the only like the things that get through are things where you have like a feature flag that's enabled in Dev that's off in staging and so then ideally QA would catch it um I would say that that's probably the number one case where things do get through is you know employees don't see it because of some kind of future fly configuration and then it happens to be something that's not covered uh by QA testing and staging and then that's how it gets through to production um but uh in general we're able to catch most things and just to understand the environments I think it's pretty clear in the back and what it means it's like different you know like servers if it's staging there's there's services that the code is deployed in in we're talking about mobile uh uh environments right like how is this differentiate is it a different app that is downloaded or or or is it based on user different flags being enabled uh in the environment like how can we imagine this these you know like the difference between the dev environment and you know like production or staging yeah I think you're I mean a lot of companies do it differently um some folks have the sort of like Dynamic configuration or like depending on the user it like Signs you into a different environment um but at oce we ship sort of like different apps uh we have like sort of separate listings on like the the Play Store and the app store for these apps and we ship them to sort of like our internal testers which are just like uh our sort of internal employees yeah I think this setup works pretty well because we're able to uh like turn on certain compile time Flags uh when we build those apps so basically like we have a development build of the app and if you ever are using you know like macros things like that uh you can enable those at the very start of the build essentially and um then like that is submitted separately so they they actually exist as like separate entities in you know App Store con environment would be a different binary like a Dev binary Dev compiled binary and obviously with combined with the user gets like if it's an employee they get like different feature Flags yep exactly so these apps are just never submitted publicly yeah yeah there's also like a bunch of like debugging information that we include like extended logs uh like more crash reporting uh so you know they're a little bit heavier in the sense that like we're um sort of like measuring more things and like uh handling errors a bit differently um and you know the apps that we ship to production are a bit more sort of minified more efficient uh just because like our user base is a little bit different but do I understand it correctly that K notion deliberately made this decision to allow for offline work even if the network drops across web and and and mobile is this one of the reasons why this quite unusual uh backend structure and kind of client decisions have been made or or or if not what was the reason with a lot of like technical decisions sometimes it's just like historically that's the decision that was made and and that's kind of like what we ran with um and then you do this like sort of like long-term evaluation to say whether oh it was the right decision to do it this way or we need to like rewrite things in our case I Think Like the Model start started out like this um and to provide a little bit more context you know the the transactions API or the syncing API is like the two major API and points that that notion has we don't really have a lot of like other ones and these do a majority of the heavy lifting so if you wanted to like add things to your favorites or create a new block all these kind of go through that singular safe transactions API which is kind of like what we hit and the sort of request that we're sending is like super flexible so it supports a VI like a wide variety of use cases and the same thing is true for like syncing is that we can just sort of like fetch that that data and so to to sort of your earlier question like was this like an intentional decision that we made and chose it to be offline or like to support offline better I think you know as Austin mentioned I think it was part of the the motivation around it but also we just wanted to support this like super flexible data model and have it be able to handle these cases that um that are sort of like core to a user's workflow so you can think of like a good example being that notion is a like you know you're saving a lot of your like knowledge and content there you want some guarantees about what where that information is going to be be stored and um you know having things fail when you're like trying to save them like take notes feels like a really bad user experience so we want to like sort of like adjust for that and sort of build it out up front it's just fascinating how important the data model is for you know years later like it's it's just an interesting learning that I would have not thought about it but it kind of makes sense right if a product is successful as successful as notion has been it's it's going to be around and the documents will hopefully you know there will be users who've been using it from day one working on the same documents even and you need to support that yeah and you know if you think about sort of the Counterpoint which is that you know we talked about trade-offs a little bit but you know Notions data model being this flexible also makes it you know a little bit difficult to do other things that users might expect us to be able to do um and so you know you're always deciding what you know what is the layer that you want to operate in and what decisions do you want to make to support these like core use cases that are important to the the product that you're building taking a step outside of notion where do you see the mobile engineering industry heading if we let's say try to forecast for the next five years and what what areas do you think we're going to see progress on on Android and on iOS if you want to start Austin yeah sure um the first thing that comes to mind for me is uh like our mobile app architecture uh K mentioned earlier you know the the switch to Jetpack and POS and Swift UI these are uh these declarative Frameworks um that I feel like fit with a little bit different of a model they're closer to react uh than they are to uh like what we have been working with historically on mobile um you know for example uh at the time that Swift UI was released I think the predominant uh architecture pattern was mvvm or like model view view model um that came from like model view controller uh but now I see it much more frequently uh people using kind of a store SL like Redux pattern that you kind of see on the web um where you have you know some store class that holds a you know state struct or something like that and then you might even add on like a reducer to handle the actions um and I think that's just like a byproduct of the way that compose and Swift UI uh like handle view rendering as you know a process of like St changes to State um so I feel like that gives you a lot more control out out of you know uh State changes and I also feel like it's nice in that you know we're getting closer to parity with web in terms of architecture so I'm interested to see what patterns emerge over the next few years yeah I'll add that I think like mobile has been around I think long enough now that we're starting to see sort of like more mature patterns emerge and sort of similar to like web I think a lot of folks when they're like now exposed to Mobile have like good guiding principles on how to build a mobile app or how to think about mobile architecture whereas maybe like you know 5 or 10 years ago it was kind of like the wild west you could just do whatever you wanted to and you'd be sort of relatively okay but I think now if you're thinking about like scaling a mobile product um you know thinking about architecture is like a core part of how you think about building that product um and so having more mature architectures I think kind of where we're I imagine we'll go in the next five or so years is just better guidance around how to you know think about mobile and mobile at scale and what advice would you give to mobile Engineers who would like to grow let's say a mid-level engineer who would really like to get to that senior potential to that staff level uh thing and you know they're working on either iOS or Android what would you suggest for them to keep growing professionally um maybe I'll start by saying that you know early in your career I think a lot of your role is just being a good executor and just taking like you know the tasks that you've been assigned and the projects that you're working on or that you're responsible for and just like shipping them on time and then you know doing sort of like a a really good job with like craft and quality um that's sort of like sort of the foundational work that you're doing sort of early early on in your career I think what I found particularly helpful as you you know think about growing into like more senior roles is thinking more about problem finding and thinking about how the work that you're doing relates to the the sort of outcomes of the business thinking about how you can sort of move the needle on the objectives of the business and and the work that you're doing can drive those outcomes so if you're like sort of thinking about that shift between like you know kind of like career to like later career is keeping that top of mind and being sort of intentional about the projects that you work on always asking like why why is why is this the project to do at this time you know I think that's a good guiding principle yeah I would I would agree with that um I think a big distinction that we make between senior and staff at notion is uh like are you just executing well versus like are you you know kind of moving business metrics and so like your ability to identify those business metrics and then make an impact uh I think makes a meaningful difference um I would also say transitioning from like executing well personally to uh helping others or providing Frameworks or tools for others to you know make their jobs easier essentially so that could mean documentation or or like building out uh you know Frameworks that are used by multiple people um that can kind of take a variety of forms uh even just pairing with with other folks on the team or like helping new people ramp up there are kind of like a lot of opportunities uh to work outside your current you know product or feature that you're working on um yeah that's I you still have to be a good executor on top of that like yeah of course yeah so you're doing that in addition to execution and would you recommend on focusing on on just you know the mobile technology or your mobile stack that you're doing let's say you're doing Android just focus on Android or to kind of Branch out a little bit and like dip your toes here and there as well yeah I think it can depend on your circumstances I do feel like going deeper in Mobile is still a pathway to growing as an engineer um you know like throughout this conversation we kind of talked about a lot of depth that exists within mobile and if you're working on an app where you have an opportunity to do something like that uh where you know you can either go deep on something like performance or on these service layers like you know syncing transactions like there there's a lot of complexity uh that that still exists within mobile um but I think there are other circumstances where you know 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 or build out a basic version of the back end um you know one of the first projects that I worked on at notion was uh um like upgrading to uh notion Plus on the mobile app so we had to build out uh the backend for that um so like there are opportunities to work on you know kind of projects that expand just beyond the scope of mobile awesome well thank you so with this let's just wrap with rapid questions if that's okay and and these are just really so so for the first one I'll I'll ask you know like both of you and then I'll I'll have the the ones separate for for the thing so rapid questions do you use an AI coding tool for your day today and if so which one Austin yeah um we started using cursor uh at notion and I'm super excited about it you know it runs on top of uh claw 3.5 Sonet um which I think works really well and I think the differ app really for cursor is the the interface of like how you really think about like AI completions um like there's a running joke at the org where you're just like hitting tab the entire time to like accept the suggestions and you know the reality is that like these tools will only get better so you know if you're not using an AI coding tool like consider it play around with it see see if it works for you yeah and I I'm I'm impressed to hear because mobile is one of the areas where the tooling is just it's not it's a lot more sophisticated we know that there's a lot of other IDs so the fact that you're using it to me is very encouraging and the fact fact that you have like such positive experiences and yeah like I think I can like try it out if you're not already doing it now my next next question is a bit more kind of divisive so Austin Swift or objective c and why yeah um I would definitely say Swift uh no hesitation I 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 larg um I the the community around it I think is is really great and I guess just like certain aspects of the language um you know I feel like it's continually being improved you know recently the addition of stuff like async A8 uh I feel like there are a lot of exciting things kind of around the language um that that keep me with Swift all right and K to you Java or cotlin I mean that's not even a a fair question but I'm going to ask it anyway no I think cotlin is definitely like the the winner here um to me Colin feels like just like a better version of java I started programming by learning how to write Java and so you know it has a special place in my heart um but you know it's like the languages are maturing now a Callin just feels like you know it has so much of the syntactic sugar that just makes development a breeze um and you know first class Primitives for things like concurrency and and reactivity or like just like cherries on top of uh of what cotton off first great and finally can you share a non-fiction book that you've recently read and you've enjoyed yeah I recently read Skunk Works by Ben Rich which is about the engineering team at Lockheed Martin um kind of during a period of very critical years uh you know they worked on the SR71 Blackbird like a lot of very very uh complex projects um and yeah I feel like it's just very inspirational for engineering teams uh in general a lot of very difficult problems to solve yeah that's a great book um highly recommend that one too but uh I've been recently rereading a philosophy of software design by John osterhouse um and you know it's about sort of managing complexity in software and sort of like the tricks that you can use to sort of reframe some of your problems so that the problem itself is simpler to solve uh but yeah highly recommend as well awesome well thank you very much for for being here and and for sharing all these insights thank you for having us I appreciate it thanks very much to Austin and K for sharing all these details and going deep into the specifics on mobile engineering at notion if you enjoyed the podcast please do subscribe in your favorite podcast platform and on YouTube 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 thanks and see you at the next one for
Summary
This episode explores how Notion's mobile team, a small engineering group of 11 engineers, built and rewrote their iOS and Android apps from a web view-based approach to a fully native architecture. They focus on performance, incremental development, and a unique engineering culture centered around RFCs, weekly performance reviews, and cross-platform collaboration to deliver a fast, reactive mobile experience for over 100 million users.
Key Points
- Notion's mobile team is small (11 engineers) but responsible for a critical product used by tens of millions of mobile users.
- The team re-wrote their mobile apps from a web view/Cordova/RN hybrid to a fully native architecture to solve performance issues.
- The rewrite was done incrementally, starting with the Home tab, to manage risk and validate the approach before tackling the complex editor.
- Key performance metrics like 'Initial Home Render' were prioritized, and a weekly performance review meeting was established to track progress.
- Notion uses a unique engineering culture with RFCs, a structured review process, and a 'consultant' model where mobile engineers support other teams.
- The team uses Swift and Kotlin with modern frameworks like Swift UI and Jetpack Compose, despite early challenges with pre-1.0 versions.
- To manage complexity, they adopted a modular architecture with over 100 modules on iOS, enabling fast builds and independent feature development.
- The release process involves weekly builds with a progressive rollout, while a nightly public beta provides early feedback.
- Feature flags are used extensively (in the hundreds) to manage risk, enable staged rollouts, and quickly roll back problematic changes.
- The team uses AI coding tools like Cursor and prioritizes fast build times to maintain developer velocity.
Key Takeaways
- For complex products, a performance-first approach is crucial; start by identifying and fixing the most impactful user experience issues like app startup time.
- Large-scale rewrites can be managed effectively by breaking them into smaller, incremental phases rather than attempting a big bang approach.
- A small team can be highly effective by adopting a structured engineering culture with clear processes like RFCs and dedicated performance reviews.
- Modular architecture is essential for scalability; it enables fast builds, independent development, and easier maintenance of large codebases.
- Leverage modern tooling like AI coding assistants and fast build systems to maintain high developer velocity and prevent technical debt.