Atlassian Frontend Development Interview Questions & Answers
Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Atlassian hiring for Frontend Development roles
Atlassian builds team collaboration and software development tools such as Jira, Confluence, Trello, Bitbucket and Jira Service Management. It runs a significant engineering team in Bengaluru and follows a distributed work policy. Hiring in India covers software engineers, quality and reliability engineers, data engineers and data scientists who work on product analytics and platform features.
For Frontend Development roles, this Atlassian practice set focuses most on Frontend Testing (7), Browser APIs (4), TypeScript (4), Build Tools and Tooling (4). It has 3 easy, 16 medium, 11 hard questions, so you can start easy and work up to the harder ones.
Company type
Product
Headquarters
Sydney, Australia
Main India offices
Bengaluru
Atlassian Frontend Development interview process
Online coding assessment
Coding round
System design or data round
Values round
Hiring manager round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for AtlassianStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
Detect offline status and retry queued requests when the connection returns.
Listen for online and offline events and keep a small queue:
const queue = [];
async function send(req) {
if (!navigator.onLine) { queue.push(req); showBanner('You are offline'); return; }
await fetch(req.url, req.options);
}
window.addEventListener('online', async () => {
hideBanner();
while (queue.length) await send(queue.shift());
});
window.addEventListener('offline', () => showBanner('You are offline'));
navigator.onLine can report true on captive networks, so treat failed fetches as offline too. Persist the queue in IndexedDB for reliability.
Tokens go in CSS with the @theme directive:
@import 'tailwindcss';
@theme {
--color-brand-500: #2563eb;
--color-brand-700: #1d4ed8;
--font-display: 'Poppins', sans-serif;
--radius-card: 12px;
}
/* usage in markup */
/* <button class='bg-brand-500 hover:bg-brand-700 rounded-card font-display'> */
Tailwind generates utilities like bg-brand-500 from these variables and also exposes them as CSS custom properties for use in plain CSS.
03
Write a card that changes layout based on its container width.
Use a container query so the card adapts wherever it is placed:
.card-wrapper {
container-type: inline-size;
}
.card {
display: grid;
gap: 1rem;
}
@container (min-width: 420px) {
.card {
grid-template-columns: 160px 1fr;
align-items: center;
}
}
In a narrow sidebar the image stacks above text; in a wide main column it sits beside the text, with no viewport media queries.
satisfies checks that a value matches a type without changing the value's inferred type. With const routes = { home: '/', about: '/about' } satisfies Record<string, string>, TypeScript validates the shape but still knows the exact keys, so routes.contact is an error. A plain type annotation would widen the type and lose those specific keys. It is ideal for configuration objects and theme tokens.
05
Tailwind classes built dynamically like 'bg-' + colour work locally but are missing in production. Why?
Tailwind finds classes by scanning source files for complete strings, so a class assembled at runtime never appears in the code and its CSS is not generated. The fix is to map values to full class names, such as const colours = { success: 'bg-green-600', error: 'bg-red-600' }. If truly dynamic values are needed, use inline styles with CSS variables or explicitly safelist those classes.
I would mix strategies by page type. Category and product pages need SEO and fast LCP, so I would use static generation with incremental revalidation or server rendering with CDN caching. Cart, checkout and account pages are personalised, so server rendering without shared caching or client rendering works. Prices and stock can be fetched fresh on the client. Frameworks like Next.js, Nuxt and Astro support this per-route choice.
Let callers specify the expected response type:
async function getJson<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
return res.json() as Promise<T>;
}
interface Course { id: number; title: string; }
const courses = await getJson<Course[]>('/api/courses');
courses[0].title.toUpperCase();
The cast trusts the server, so for untrusted data validate with a schema library like Zod before returning.
Visual regression testing captures screenshots of pages or components and compares them pixel by pixel with approved baselines, flagging unexpected visual changes such as broken spacing or wrong colours. Tools include Playwright's toHaveScreenshot, Chromatic with Storybook and Percy. To avoid false failures, run in consistent containers, disable animations, and mask dynamic content like dates. It catches CSS bugs that functional tests miss.
10
Management requires 100 percent code coverage, but bugs still appear. How do you respond?
Coverage shows which lines ran, not whether the behaviour was verified, so tests can execute code without meaningful assertions. I would explain this with an example and propose a balanced target, perhaps 80 percent on business logic, combined with quality measures like mutation testing, critical user flows covered by end-to-end tests and tracking escaped defects. Effort is better spent on risky areas than on trivial getters.
11
Register a service worker that caches static assets with a cache-first strategy.
Register from the page, then handle install and fetch in sw.js:
// main.js
if ('serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js');
// sw.js
const CACHE = 'static-v3';
self.addEventListener('install', e => {
e.waitUntil(caches.open(CACHE).then(c => c.addAll(['/', '/app.css', '/app.js'])));
});
self.addEventListener('fetch', e => {
e.respondWith(caches.match(e.request).then(hit => hit || fetch(e.request)));
});
Changing the cache name on each release lets the activate step delete old caches.
12
Production builds take eight minutes on an old webpack setup. How would you speed them up?
I would profile the build to find slow loaders and plugins. Quick wins include replacing Babel and Terser with SWC or esbuild, enabling persistent filesystem caching, and removing unused plugins. For a bigger gain, I would evaluate migrating to Vite or Rspack, which keeps webpack-compatible config. In CI, caching dependencies and build outputs and running only affected packages in a monorepo cut time further.
Component-driven development builds UIs from the bottom up as small, reusable, isolated components, such as buttons and inputs, composed into larger patterns like forms and pages. Each component has a clear API through props or attributes and is developed and documented in isolation, often in Storybook. Composition over configuration keeps components flexible. This approach enables design systems, parallel work and easier testing.
14
What is Interaction to Next Paint and what usually makes it poor?
INP replaced First Input Delay in 2024. It measures the delay from a click, tap or key press until the next frame is painted, across all interactions on the page, reporting roughly the worst one. Poor INP usually comes from long JavaScript tasks blocking the main thread, heavy event handlers, large re-renders and expensive layout work after interaction. Breaking up tasks and showing immediate visual feedback improves it.
15
End-to-end tests fail randomly in CI about one run in five. How do you stabilise them?
I would collect traces, videos and screenshots of failures to see what actually happened. Usual fixes are replacing fixed waits with auto-waiting assertions, waiting for specific network responses, seeding isolated test data per test, mocking unstable third-party services, and disabling animations. I would quarantine persistently flaky tests with a tracking ticket rather than letting the team ignore red builds, and retry only as a temporary measure.
16
TypeScript types say a field exists, but the app crashes because the API did not send it. How do you prevent this?
TypeScript only checks at compile time; it cannot guarantee what a server returns at runtime. I would validate responses at the boundary with a schema library like Zod or Valibot, deriving TypeScript types from the schema so they never drift. Invalid data then fails clearly with a logged error and a fallback UI. Generating types from OpenAPI specs also keeps frontend and backend contracts aligned.
17
What are the URL and URLSearchParams APIs used for?
The URL constructor parses a URL into parts like hostname, pathname and searchParams, and builds valid URLs without manual string concatenation. URLSearchParams reads and writes query strings, handling encoding automatically, for example params.get('page') or params.set('sort', 'price'). They prevent bugs with special characters such as spaces and ampersands in search terms, and are the clean way to sync filters with the address bar.
18
Create a new Vite project with TypeScript and run it.
Use the official scaffolding tool:
npm create vite@latest my-app -- --template vanilla-ts
cd my-app
npm install
npm run dev # starts the dev server with HMR
npm run build # type-checks and builds to dist/
npm run preview # serves the production build locally
Templates also exist for react-ts, vue-ts and svelte-ts. The dist folder contains static files ready for any web server or CDN.
Extend HTMLElement and register a tag name containing a hyphen:
class RatingStars extends HTMLElement {
connectedCallback() {
const value = Number(this.getAttribute('value') || 0);
const root = this.attachShadow({ mode: 'open' });
root.innerHTML = `<style>span { color: var(--star-color, orange); }</style>
<span role='img' aria-label='${value} out of 5'>${'*'.repeat(value)}</span>`;
}
}
customElements.define('rating-stars', RatingStars);
// usage: <rating-stars value='4'></rating-stars>
The custom property lets the page theme it despite Shadow DOM isolation.
20
What is the guiding principle of Testing Library and why query by role?
Testing Library encourages testing the way users interact: find elements by what they see and hear, not by implementation details like class names or component internals. getByRole('button', { name: 'Submit' }) is preferred because it also verifies the element is accessible. Tests written this way survive refactors and catch real accessibility problems. Test ids are a last resort when no accessible query works.
21
Mock fetch in a Vitest test to check error handling.
Stub the global fetch and assert behaviour:
import { it, expect, vi, afterEach } from 'vitest';
import { loadCourses } from './api';
afterEach(() => vi.unstubAllGlobals());
it('returns an empty list when the server fails', async () => {
vi.stubGlobal('fetch', vi.fn().mockResolvedValue(
new Response('Server error', { status: 500 })
));
const result = await loadCourses();
expect(result).toEqual([]);
expect(fetch).toHaveBeenCalledWith('/api/courses');
});
For larger suites, MSW handlers are cleaner than stubbing fetch in every test.
22
Search results sometimes show data for an older query. What is happening?
This is a race condition: requests for 'ja' and 'java' are in flight together, and if the older one responds last, it overwrites the newer results. I would cancel the previous request with AbortController, or tag each request with an id and ignore responses that are not the latest. Debouncing the input reduces the number of requests, and caching repeated queries makes responses faster and more consistent.
23
The bundle analyser shows two copies of the same library. How do you fix it?
Duplicates happen when different packages depend on incompatible versions, so the package manager installs both. I would run npm ls library-name or pnpm why to see who requires which version, then update dependents to a common version, use overrides or resolutions to force one compatible version, or configure resolve.dedupe in Vite. Duplicate framework copies are especially harmful because they can break shared state and context.
24
How have you built a testing culture in a frontend team?
Situation: my team had almost no automated tests and frequent regressions. Task: as tech lead, I wanted testing to become a habit, not a mandate. Action: I set up Vitest and Playwright with examples, ran two short workshops, required tests only for bug fixes at first, and celebrated bugs caught in CI. Result: within six months, most pull requests included tests and production regressions dropped significantly.
25
Build an API client that refreshes an expired access token once and retries.
I would first classify state: server data moves to a data-fetching cache like TanStack Query, URL-worthy state such as filters moves to query parameters, and truly local state moves back into components. What remains global, like user session and theme, goes into a small, well-defined store or context split by concern. Composition patterns, passing components as children, also remove much prop drilling.
28
Write a DeepReadonly type using mapped and conditional types.
Promises without a catch produce unhandled rejections that do not stop the app but hide failures. I would add a global window.addEventListener('unhandledrejection') handler and window.onerror that report errors to a monitoring tool like Sentry with source maps. In code, every async call should have try and catch or a .catch, and ESLint rules such as no-floating-promises in TypeScript projects catch missing handlers.
Tips to crack the Atlassian Frontend Development interview
Read Atlassian's company values, such as Don't #@!% the Customer and Open Company, No Bullshit, for the values interview.
Use Jira and Confluence hands-on so you can discuss workflows, agile boards and possible product improvements.
Practise writing clean, well-structured code, as Atlassian coding rounds often value code quality and testing, not just correctness.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; Atlassian interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Atlassian Frontend Development interview?
Candidates usually go through 5 stages: Online coding assessment; Coding round; System design or data round; Values round; Hiring manager round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the Atlassian Frontend Development interview?
This practice set leans on Frontend Testing (7), Browser APIs (4), TypeScript (4), Build Tools and Tooling (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Atlassian interviewers ask you to walk through real work.
Are these the exact questions asked at Atlassian?
No. These are curated practice questions that match the skills and difficulty usually tested in product interviews like Atlassian's. They are not a leaked or verified list of past questions.
Where does Atlassian hire Frontend Development professionals in India?
Atlassian has large teams in Bengaluru. Openings and locations change often, so check the Atlassian careers page and filter by city and experience.
Frontend Development questions for similar companies