Paytm Frontend Interview Questions
Broad fundamentals across JavaScript, React and CSS.
Paytm covers payments, commerce and financial services, with many separate web products and teams. Interview loops vary by team more than at some companies, but they are usually described as fundamentals-first.
Expect direct questions on JavaScript concepts, React basics and CSS, some coding, and a discussion of your current project.
- Questions
- 15, 5 with free answers
- Interview rounds
- 4
- Last reviewed
- October 2026
Paytm frontend interview process
The usual shape of the loop. A guide to what to prepare, not a promise of what you will get.
- 1
Technical round 1
JavaScript concepts, output-based questions and small coding problems.
- 2
Technical round 2
React, state management, CSS, and a small component or a feature to design.
- 3
Hiring manager
A deep dive into a project you owned.
- 4
HR
Role, team and logistics.
What interviewers tend to look for
- Explaining a concept clearly with a short example.
- Predicting the output of tricky snippets: hoisting, equality, the event loop.
- CSS layout and specificity without looking things up.
- Knowing your own project in depth, including what you would change.
Your Paytm mock interview
15 questions. Type an answer under each one and an AI reviewer scores it and tells you what you missed. Stuck on one? Ask for a hint. A free account gets 3 AI replies a day.
Your mock interview
0 of 15 answered
Answer a question and your score shows up here.
JavaScript
6 questions- Question 1 of 15JavaScript
Paytm interviewer
Explain hoisting and the temporal dead zone.
Model answer
Declarations are registered when a scope is created, before any of its code runs. What differs is the starting value:
varis hoisted and set toundefined, so reading it early givesundefined.- Function declarations are hoisted with their body, so you can call them above where they are written.
let,constandclassare hoisted but left uninitialised. Reading them before the declaration line throws aReferenceError.
The stretch between the start of the scope and the declaration line is the temporal dead zone.
console.log(a); // undefined console.log(b); // ReferenceError var a = 1; let b = 2;Function expressions follow their variable:
var fn = function () {}isundefineduntil that line runs. - Question 2 of 15JavaScript
Paytm interviewer
What is a closure? Give a practical use for one.
Model answer
A closure is a function together with the scope it was created in. The function keeps access to the variables of that scope even after the outer function has returned.
function createCounter() { let count = 0; // private: nothing outside can touch it return { increment: () => ++count, value: () => count, }; } const counter = createCounter(); counter.increment(); counter.value(); // 1Practical uses: private state as above, function factories, and utilities such as
debounceandmemoize, which keep a timer or a cache between calls.The cost to mention: a closure keeps its captured variables alive for as long as the function is reachable, so a long-lived callback holding a large object is a memory leak.
- Question 3 of 15JavaScript
Paytm interviewer
What is the difference between ==, === and Object.is?
Model answer
===compares without converting types.==converts first, which gives results such as'1' == 1andnull == undefinedbeing true. The one widely accepted use of==isvalue == null, which checks for bothnullandundefined.Object.isbehaves like===with two differences:Object.is(NaN, NaN)is true, andObject.is(+0, -0)is false.All three compare objects by reference, so
{} === {}is false.Worth adding in a React interview: React uses
Object.isto decide whether state or a dependency changed, which is why mutating an object in place does not trigger a re-render. - Question 4 of 15JavaScript
Paytm interviewer
Explain the event loop. In what order do a setTimeout, a promise callback and synchronous logs run?
Model answer
JavaScript runs on one call stack. When the stack is empty, the event loop first runs every queued microtask (promise callbacks,
queueMicrotask,MutationObserver), then takes one macrotask (a timer, an I/O callback, a UI event), and the browser may render in between.console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D'); // A, D, C, BSynchronous code finishes first (A, D). The promise callback is a microtask, so it runs before the timer, which is a macrotask, even with a 0 ms delay.
With
asyncfunctions, everything after anawaitis scheduled as a microtask. A common follow-up is a longer snippet mixing both; work through it queue by queue instead of guessing. - Question 5 of 15JavaScript
Paytm interviewer
Write a polyfill for Array.prototype.reduce.
Model answer
Array.prototype.myReduce = function (callback, initialValue) { let index = 0; let accumulator = initialValue; if (arguments.length < 2) { // No initial value: use the first element that exists. while (index < this.length && !(index in this)) index++; if (index >= this.length) { throw new TypeError('Reduce of empty array with no initial value'); } accumulator = this[index++]; } for (; index < this.length; index++) { if (index in this) { accumulator = callback(accumulator, this[index], index, this); } } return accumulator; };The details that separate answers: checking
arguments.lengthinstead ofinitialValue === undefined(passingundefinedon purpose is valid), throwing on an empty array with no initial value, and skipping holes in sparse arrays.mapandfilterare the usual warm-ups. Both take the same(value, index, array)callback and an optionalthisArg. - Question 6 of 15JavaScript
Paytm interviewer
How do ES modules differ from CommonJS, and why does tree shaking depend on ES modules?
Model answer
ES module
importandexportstatements are static. They sit at the top level and are resolved before any code runs, so a bundler can see exactly which exports are used and drop the rest. That removal is tree shaking.CommonJS
requireis an ordinary function call. It can run inside anif, with a computed path, and it returns a plain object, so the bundler cannot be sure what is unused.Other differences: ES module imports are live bindings to the exported variable, ES modules load asynchronously and support top-level
await, and they always run in strict mode.Tree shaking also needs the library to be side-effect free, which packages declare with
"sideEffects": falseinpackage.json. Dynamicimport()is the tool for code splitting: it returns a promise and creates a separate chunk.
TypeScript
1 question- Question 7 of 15TypeScript
Paytm interviewer
What is the difference between a type alias and an interface?
Model answer
Both can describe the shape of an object, and for that job they are close to interchangeable. The differences:
- An
interfacecan be declared more than once and the declarations merge. That is how you add a field toWindowor to a library's types. - An
interfaceextends others withextends. Atypecombines with&. - A
typecan name anything: unions, tuples, primitives, mapped types and conditional types. An interface can only describe an object or function shape.
type Status = 'idle' | 'loading' | 'error'; // only a type can do this interface User { id: string; name: string; } interface Admin extends User { permissions: string[]; }A sensible rule to state: use either for object shapes, use
typewhen you need a union or a computed type, and stay consistent within a codebase. - An
React
3 questions- Question 8 of 15React
Paytm interviewer
How does React decide what to update in the DOM? Why do list items need keys?
Model answer
Rendering calls your components and produces a tree of elements. React compares that tree with the previous one (reconciliation) and then applies only the differences to the DOM, in a separate commit step.
Two rules keep the comparison fast:
- A different element type at the same position (a
divbecoming asection, orLoginbecomingDashboard) means React throws that subtree away and builds a new one. Its state is lost. - The same type at the same position means React keeps the instance and its state and updates the props.
In a list, position is not enough, because items move. A
keytells React which item is which between renders. With the array index as the key, inserting at the top makes every item look changed, and state such as a typed input value ends up attached to the wrong row. Use a stable id from the data.A useful trick follows from the same rule: changing a component's
keyon purpose resets its state. - A different element type at the same position (a
- Question 9 of 15React
Paytm interviewer
What is the difference between a controlled and an uncontrolled component?
Model answer
In a controlled input, React state holds the value. You pass
valueandonChange, and every keystroke goes through state. That makes validation, formatting and conditional UI easy.In an uncontrolled input, the DOM holds the value. You give it a
defaultValueand read the result on submit, through a ref orFormData.// Controlled <input value={email} onChange={(e) => setEmail(e.target.value)} /> // Uncontrolled <form onSubmit={(event) => { event.preventDefault(); const data = new FormData(event.currentTarget); save(data.get('email')); }} > <input name="email" defaultValue="" /> </form>Uncontrolled inputs re-render less, which is why form libraries such as React Hook Form use them, and React 19 form actions work the same way. A file input is always uncontrolled.
The warning to recognise: an input whose
valuegoes fromundefinedto a string has switched from uncontrolled to controlled. Start it with an empty string. - Question 10 of 15React
Paytm interviewer
How do you decide where state should live, and when would you add a state management library?
Model answer
Sort the state by kind first, because each kind has a natural home:
- Local UI state (is this menu open):
useStateoruseReducerin the component. - State shared by a few siblings: lift it to their nearest common parent.
- App-wide client state that changes rarely (theme, auth): Context.
- Server state, meaning data fetched from an API: a cache library such as TanStack Query, SWR or RTK Query, or the framework's own data layer. It handles caching, deduplication, retries and refetching.
- State that should survive a refresh or be shareable (filters, page number, selected tab): the URL.
Most of what teams once put in a global store was server state. With that handled by a cache, the remaining shared client state is often small.
Reach for Redux Toolkit or Zustand when many distant components read and write the same client state, when updates need to be traceable, or when Context re-renders become a measured problem.
- Local UI state (is this menu open):
CSS
2 questions- Question 11 of 15CSS
Paytm interviewer
How does the browser decide which CSS rule wins?
Model answer
When several declarations target the same property on the same element, the cascade checks, in order:
- Origin and importance:
!importantdeclarations beat normal ones. - Cascade layers: for normal declarations, a later
@layerbeats an earlier one, and styles outside any layer beat all layers. - Specificity.
- Source order: the last one written wins.
Specificity is compared as three numbers: ids, then classes, attributes and pseudo-classes, then element names and pseudo-elements.
#nav .linkis (1,1,0) and beats.menu .item .linkat (0,3,0), because ids are compared first. An inlinestyleattribute beats any selector.Useful details:
:where()always has zero specificity, while:is()and:not()take the specificity of their most specific argument.In practice, keep specificity low and flat by styling with single classes, and use
@layerto order resets, components and utilities instead of fighting with!important. - Origin and importance:
- Question 12 of 15CSS
Paytm interviewer
How many ways can you centre an element horizontally and vertically?
Model answer
/* 1. Grid: the shortest */ .parent { display: grid; place-items: center; } /* 2. Flexbox */ .parent { display: flex; justify-content: center; align-items: center; } /* 3. Absolute positioning, size unknown */ .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } /* 4. Absolute positioning with auto margins, size known */ .child { position: absolute; inset: 0; margin: auto; width: 200px; height: 100px; }Interviewers usually want you to explain one of them. In the third,
topandleftmove the child's corner to the middle of the parent, and the transform shifts it back by half of its own size, because percentages intranslaterefer to the element itself.For horizontal centring only:
margin-inline: autoon a block with a width, ortext-align: centerfor inline content.
Browser, performance and system design
2 questions- Question 13 of 15Browser, performance and system design
Paytm interviewer
Compare cookies, localStorage and sessionStorage. Where should an auth token be stored?
Model answer
- Cookies: about 4 KB each, sent to the server with every request to their domain. They can have an expiry and security flags.
- localStorage: around 5 MB per origin, kept until cleared, shared by all tabs. Never sent to the server. The API is synchronous.
- sessionStorage: the same API, limited to one tab and cleared when it closes.
- IndexedDB: a larger, asynchronous database for structured data, used for offline apps.
For a session or auth token, the safest common choice is a cookie with three flags:
HttpOnly: JavaScript cannot read it, so a script injected through XSS cannot steal it.Secure: sent over HTTPS only.SameSite=LaxorStrict: not sent on most cross-site requests, which blocks most CSRF.
Anything in
localStoragecan be read by any script running on the page, including a compromised dependency. That is why long-lived tokens do not belong there. If a design does keep a token in JavaScript, keep it in memory and make it short-lived, with the refresh token in an HttpOnly cookie. - Question 14 of 15Browser, performance and system design
Paytm interviewer
What is the difference between async and defer on a script tag? What are preload and prefetch?
Model answer
- A plain
scriptstops the HTML parser while the file downloads and runs. asyncdownloads in parallel and runs as soon as the file arrives, pausing the parser at that moment. Order is not guaranteed. Use it for independent scripts such as analytics.deferdownloads in parallel and runs after the document has been parsed, in the order the scripts appear, just beforeDOMContentLoaded. Use it for application code.type="module"scripts are deferred by default.
Resource hints tell the browser about things it has not discovered yet:
preload: this page needs the file soon, so fetch it now at high priority. Used for a font, or a hero image referenced from CSS.prefetch: a later navigation will probably need this, so fetch it when idle.preconnect: open the connection to another origin early.fetchpriority="high"on an image raises its priority, which helps LCP.
Preloading too much is a common mistake. Everything marked urgent competes with what really is.
- A plain
Machine coding
1 question- Question 15 of 15Machine coding
Paytm interviewer
Build a pagination component.
Model answer
Props:
page,totalPagesandonChange. The interesting part is deciding which page numbers to show when there are many.function getPages(current, total, siblings = 1) { const pages = []; const start = Math.max(2, current - siblings); const end = Math.min(total - 1, current + siblings); pages.push(1); if (start > 2) pages.push('...'); for (let p = start; p <= end; p++) pages.push(p); if (end < total - 1) pages.push('...'); if (total > 1) pages.push(total); return pages; } getPages(6, 20); // [1, '...', 5, 6, 7, '...', 20] getPages(1, 5); // [1, 2, '...', 5]- The first and last page are always shown, with the current page and its neighbours in between.
- Previous is disabled on page 1 and Next on the last page.
- Wrap it in a
navwith anaria-label, and mark the current page witharia-current="page". - It is a controlled component. It does not fetch anything itself.
Follow-ups: keeping the page in the URL so that it survives a refresh and can be shared, cancelling the previous request when the page changes quickly, a page size selector, and when to use a cursor with a Load more button instead.
Practise for Paytm
Reading answers is the easy half. These problems run in the browser against real tests.
