Full Stack Developer Internship at AssureMe: Building an Admin Dashboard in a Startup
There is a gap between writing software in a controlled environment and writing software that actually ships. This internship was my first sustained exposure to that gap, and a useful place to learn what closing it requires.
Over three months at AssureMe, I owned real deliverables. I made architectural decisions, shipped code under time pressure, and worked through tradeoffs that tutorials and coursework rarely surface. This post documents what I built, what I learned, and what I would approach differently today.
Internship Overview
About the Company
AssureMe is an early-stage startup operating with roughly 50 people. The engineering team is small, which means decisions move fast and engineers carry meaningful ownership over the things they build.
Working remotely in that context requires a specific kind of discipline: low communication overhead, but also low tolerance for ambiguity. When something is unclear, it stays unclear until someone asks. I learned early that asking was almost always the right call.
My Role and Responsibilities
A quick summary before the detail:
- Role: Full Stack Developer Intern
- Company: AssureMe (early-stage startup, ~50 people)
- Duration: July 2025 to September 2025
- Mode: Remote
- Key Responsibilities: Admin dashboard development, web page builds, SEO improvements, Lighthouse optimization, performance engineering
- Core Technologies: Frontend frameworks, monorepo tooling, static generation, image optimization pipelines (specific stack details omitted where proprietary)
- Primary Learning Areas: Frontend architecture, performance optimization, cross-functional communication, ownership under ambiguity
What Does a Full Stack Developer Intern Actually Build?
This is probably the most common question about internships at early-stage companies. The honest answer: more than you expect, with less handholding than you are used to.
My work across the three months included:
- Admin Dashboard built from scratch, owned end to end
- Three to four additional web pages developed independently
- Improvements to existing pages, including bug fixes and UI refinements
- SEO work across multiple pages, from meta tags to semantic structure
- Lighthouse score optimization covering Performance, Accessibility, and Best Practices
- Performance engineering, with a focus on static generation and asset optimization
No single area dominated the whole internship. The scope shifted week to week, which kept the learning curve consistently steep.
Architecture and Development
Admin Dashboard: Starting with the Right Questions
The Admin Dashboard was my primary deliverable. Nothing existed before I started, which meant I was making structural decisions without much precedent in the codebase to reference.
Before writing any components, I mapped what the dashboard needed to do: display data clearly, support filtering, enable administrative actions, and remain maintainable as the product scaled.
The early assumption I had to revise: I initially thought the dashboard would be straightforward because it was internal-facing. Admin tools often get treated as second-class surfaces. I quickly realized that an internal tool used daily by the operations team needs the same attention to usability as anything customer-facing.
Architecture Decisions That Mattered
I organized the code around clear separation of concerns from the start:
- Data-fetching logic kept isolated from presentation components
- Shared UI elements extracted early rather than duplicated and refactored later
- Monorepo utilities reused where they already existed, rather than rebuilt from scratch
The guiding principle was straightforward: do not over-engineer for hypothetical future requirements, but do not make choices that create friction for the next engineer who touches this code.
Handling Scope Creep and UI Edge Cases
Admin dashboards attract feature requests. Because stakeholders see them as low-risk surfaces, there is a tendency to layer on additions that delay core delivery. Getting comfortable with scoped pushback, professionally and early, was one of the more useful non-technical skills I developed.
Loading states, empty states, and error states needed explicit design attention alongside scope management. A dashboard that silently breaks under slow network conditions or partial data is not production-ready. These edge cases are easy to skip under deadline pressure and consistently expensive to patch later.
What Is a Monorepo and Why Do Startups Use It?
A monorepo is a single repository that houses multiple related projects or packages together, rather than splitting each into its own separate repository.
For a team of this size, the practical benefits are significant:
- Consistency across packages. Shared components and utilities stay in sync. No drift between different parts of the product using different versions of the same internal library.
- Simpler cross-package refactoring. Changes that affect multiple applications can happen in a single pull request with a single review.
- Shared tooling. Linting, testing, and build configuration can be standardized across the entire codebase.
The tradeoff is that the repository grows large, and understanding the dependency graph between packages takes upfront investment. Working inside it as an intern meant I had to develop a mental model of how pieces connected before I could contribute confidently.
Navigating an unfamiliar monorepo is a specific skill. You have to learn to read directory structures quickly, understand which packages are dependencies versus consumers, and trace where a given piece of logic actually lives. This skill does not get much attention in academic settings. It matters a lot in practice.
Performance and Optimization
How Do You Improve Lighthouse Scores in a Real Product?
Lighthouse is an auditing tool built into Chrome DevTools that evaluates web pages across four categories: Performance, Accessibility, Best Practices, and SEO. Each produces a score from 0 to 100.
The important framing: Lighthouse scores are a diagnostic tool, not a target to optimize for its own sake. Chasing a number without fixing underlying issues produces brittle results. The goal is to understand what the score is telling you, then fix the actual cause.
What I worked on across each category:
Performance:
- Identified render-blocking resources and addressed load order
- Reduced JavaScript bundle sizes by auditing what was being loaded on pages that did not need it
- Addressed layout shift issues that were degrading Cumulative Layout Shift scores
Accessibility:
- Corrected heading hierarchy on several pages
- Added missing ARIA attributes and ensured interactive elements had appropriate labels
SEO:
- Added and standardized meta titles and descriptions
- Ensured proper use of semantic HTML throughout pages I worked on
- Verified pages were crawlable and structured for search engine indexing
The realization that shifted my perspective: performance and SEO are not separate disciplines. A fast page with good semantic structure performs better in both Lighthouse and in search rankings. The work compounds.
How Does Static Generation Improve Website Performance?
This is the performance concept I went deepest on during the internship, and the one with the most immediate visible impact.
In a traditional server-rendered or client-rendered setup, meaningful work happens on every request. The server has to fetch data, render HTML, and send it to the browser. The client may also need to execute JavaScript before the page is usable. This introduces latency, especially on first load.
Static generation shifts that work to build time. Pages are rendered once when the application is built, producing pre-built HTML files. When a user requests the page, they receive that pre-built HTML immediately, with no server processing required in real time.
The combination of several optimizations working together is what made first visits feel instant:
- Pre-rendered HTML served directly, no waiting for server-side rendering
- CDN distribution placing the static files geographically close to users
- Optimized assets reducing the total payload the browser had to download
- Lazy loading deferring images and resources that were not immediately visible
None of these is a dramatic individual win. Together they create a first-load experience that feels significantly faster than what a non-optimized page produces.
Static generation works best for content that does not change on every request. For pages with highly dynamic, user-specific content, it requires a more nuanced approach: render the static shell of the page, then load dynamic data after the initial paint. Knowing when to apply each pattern is part of what I learned to reason about.
Image Optimization: A Practical Breakdown
Unoptimized images are one of the most consistent sources of poor Lighthouse Performance scores. The problems tend to be the same across codebases:
- Images served at full original resolution when the display size is much smaller
- Formats like uncompressed PNG or JPEG used where WebP would be significantly lighter
- Images loaded eagerly even when they are well below the fold and not immediately visible
My approach was systematic rather than ad hoc:
- Format conversion where more efficient formats were applicable
- Sizing images appropriately for their actual display context
- Lazy loading applied to images that do not need to be fetched on initial page load
The gains from image optimization are not subtle. It is often the single highest-impact change available on a page with performance issues.
Collaboration and Growth
Working Inside a Small Remote Engineering Team
At a team of this size, the cycle from idea to implementation to review is short. There is no multi-week process for UI changes. This is efficient, but it also means you develop judgment quickly or you ship things that should not have shipped.
Communication and Async Discipline
Remote work at a small company requires deliberate, specific communication. Vague status updates create noise. Specific ones, covering what is in progress, where a blocker exists, and what decisions have been made and why, create actual clarity.
I also learned to ask for help earlier than felt comfortable. Spending two days on a problem that a more senior engineer could have redirected in twenty minutes is not independent problem-solving. It is a poor use of everyone’s time.
Ownership as a Real Constraint
When something I built had an issue, it was mine to diagnose and fix. No external deadline extension. That accountability changes how carefully you work before marking something done, and it changes how thoroughly you think through edge cases before they become bugs.
Lessons and Reflection
Key Lessons in 60 Seconds
For engineers starting similar roles, here is what I would emphasize:
- Static generation is underutilized. If a page’s content does not change on every request, there is almost always a performance case for pre-rendering it.
- SEO and performance overlap significantly. Fixing one tends to improve the other.
- Admin interfaces deserve real UX attention. Internal-facing does not mean usability does not matter.
- Monorepos require a different kind of codebase literacy. Learning to navigate them is a skill worth developing deliberately.
- Edge cases are features. Loading states, empty states, and error states are not nice-to-haves.
- Ask earlier than feels right. The cost of a late question is almost always higher than the cost of an early one.
- Document decisions as you make them. The reasoning behind a non-obvious architectural choice should not live only in your head.
What I Would Do Differently Today
Clarify requirements earlier and more explicitly. I made assumptions about edge case behavior on the Admin Dashboard that led to rework. Confirming expected behavior upfront is faster than correcting it after implementation.
Write tests on core functionality from the start. Under deadline pressure, tests are the first thing deprioritized. That is consistently a false economy.
Document architectural decisions as they happen. The reasoning behind structural choices should be written down at the time, not reconstructed later from memory.
Invest earlier in understanding the deployment pipeline. I understood how to build the product well. My visibility into how it was deployed and monitored was limited. That knowledge would have grounded my performance work more concretely in production reality.
Technical Growth: What Actually Changed
The concrete difference between the start and end of this internship:
- Significantly faster at navigating large, unfamiliar codebases
- Practical understanding of frontend performance as a discipline with specific, learnable levers
- Working knowledge of monorepo architecture gained through direct experience
- Better calibration on when to dig independently versus when to surface a question
- Ability to own a complete feature from architectural decisions through delivery
These are incremental changes. They compound.
Three months is not long enough to develop deep expertise. It is long enough to develop meaningfully better instincts and to close some of the gap between building software and shipping it.
The Admin Dashboard I built is in production. The performance and SEO improvements I implemented affect real page loads for real users. That feedback loop is different from anything available in academic work, and it is one I intend to keep building toward.
Read more about my AI/ML internship experience here (post coming soon).
Ongoing Work
I am currently completing an AI/ML-focused internship. A detailed technical post covering that experience, including the engineering challenges, tools used, and lessons from working at the intersection of machine learning and production software, will be published here once the internship concludes.
About this Post
This post is written by Kaustubh Chauhan, licensed under CC BY-NC 4.0.