LINE LIFF guide: build a LIFF app with LINE Login
LIFF turns a web page into an app inside the LINE chat. What it can do, when a LINE MINI App is the better choice, and the one login mistake that lets anyone pretend to be your customer.
Key takeaways
- LIFF (LINE Front-end Framework) is a JavaScript SDK that lets a web page run inside LINE and read the customer's LINE profile with their permission.
- LINE now recommends creating new LIFF apps as LINE MINI Apps; LIFF will be merged into the LINE MINI App brand.
- `liff.getProfile()` is for showing a name and picture. To know who the customer is on your server, send the ID token and verify it with LINE.
- Use LIFF SDK v2.31.1 or later: LINE plans to restrict v2.20.0 to v2.31.0 around 24 November 2026.
LIFF is the reason a customer can tap “Book” in a LINE chat, pick a time and be done without typing a name, phone number or password. The page they see is an ordinary web app; LIFF lets it run inside LINE and know, with the customer’s permission, which LINE user they are.
This guide explains what LIFF is, how it compares with a LINE MINI App in 2026, and shows a small example with LINE Login that does the security part right. We build LIFF apps for booking, membership and registration; FoxConnect’s booking flow is one of them (see the FoxConnect case study).
What LIFF is
LIFF (LINE Front-end Framework) is a JavaScript SDK, @line/liff, plus a registration in the LINE Developers Console. You register your web app’s URL and get a LIFF ID and a LIFF URL (https://liff.line.me/<LIFF ID>). When a customer opens that URL from a chat, a rich menu button or a QR code, LINE opens your page in its in-app browser.
With the SDK, the page can:
- read the customer’s LINE profile (display name, picture) and an ID token, after they agree on the consent screen
- send messages into the chat the customer opened it from
- open the QR code reader, share to friends with the share target picker, and close the window when done
- check whether it runs inside LINE or in an external browser
The rest is up to you: any framework, any backend. That is why LIFF suits one focused task, like a booking form, a digital member card or a warranty registration.
LIFF vs LINE MINI App in 2026
A LINE MINI App is built with the same LIFF SDK. The difference used to be packaging: a MINI App is a complete service with its own channel, and once LY Corporation verifies it, it gets a verified badge and can be found through LINE search and the “Recently used” section of the Home tab.
LINE is merging the two. Since February 2025 LINE recommends creating any new LIFF app as a LINE MINI App, and its documentation says LIFF will be integrated into the LINE MINI App brand. A few things still work only in plain LIFF:
| LIFF app | LINE MINI App | |
|---|---|---|
| SDK | @line/liff |
@line/liff (same code) |
| Window size | Full, Tall or Compact | Full only |
| Apps per channel | Several on one LINE Login channel | One per MINI App channel |
| Search in LINE, verified badge | No | After verification |
| Review by LINE | No | Needed for verified status |
For a new customer-facing service we usually start as a MINI App, because moving later means a new channel and new links. Plain LIFF still fits an internal staff tool or a half-height window over the chat. The Thailand rules for MINI Apps are in our LINE MINI App in Thailand 2026 guide.
A small example with LINE Login
Create a LINE Login channel (or a MINI App channel), add a LIFF app with your page’s URL, and give it the openid and profile scopes. Then, in the browser:
npm install @line/liff
// app.js (browser)
import liff from '@line/liff';
await liff.init({ liffId: 'YOUR_LIFF_ID' });
if (!liff.isLoggedIn()) {
// Inside LINE the customer is already logged in; in an external browser this opens LINE Login.
liff.login();
} else {
// For the screen only: show the name and picture.
const profile = await liff.getProfile();
document.querySelector('#name').textContent = profile.displayName;
// For your server: the ID token, which the server verifies with LINE.
await fetch('/api/session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idToken: liff.getIDToken() }),
});
}
And on the server (Node.js 22 or later, Express):
// server.mjs
import express from 'express';
const app = express();
app.post('/api/session', express.json(), async (req, res) => {
// Ask LINE whether the token is genuine, unexpired and issued for our channel.
const check = await fetch('https://api.line.me/oauth2/v2.1/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
id_token: req.body.idToken ?? '',
client_id: process.env.LINE_LOGIN_CHANNEL_ID,
}),
});
if (!check.ok) return res.sendStatus(401);
const claims = await check.json();
// claims.sub is the verified LINE user ID: look up or create the customer with it.
res.json({ lineUserId: claims.sub, name: claims.name });
});
app.listen(3000);
The mistake to avoid: trusting the browser
A common LIFF security bug is a server that believes whatever user ID the page sends. liff.getProfile(), liff.getDecodedIDToken() and any user ID in a URL or request body all come from the browser, and anyone can change them with the developer tools. If your API then returns “this customer’s bookings” for that ID, one customer can read or cancel another’s.
The rule is short:
- Display may use
getProfile()or the decoded token. - Identity on the server comes only from a token the server verified: the ID token through the verify endpoint above, or the access token from
liff.getAccessToken()checked with LINE before you call the profile API with it. - Never decode a token on the server and use it without checking its signature, audience and expiry. The verify endpoint does all three for you.
Keep the SDK current as well. LINE has deprecated LIFF v2.28.0 for a security issue and plans to restrict v2.20.0 to v2.31.0 around 24 November 2026, so use v2.31.1 or later (v2.31.2 is current in October 2026).
Next steps
If the LIFF app needs to send reminders or confirmations, you will also use the Messaging API: our LINE Messaging API guide covers it. For the big picture of which LINE tool fits, read LINE OA vs LIFF vs LINE MINI App. To have a LIFF app or MINI App built, see LIFF app development and our other LINE development services.
Frequently asked questions
What is a LIFF app?
A web app that opens inside LINE through a LIFF URL. With the LIFF SDK it can read the customer's LINE profile, send messages into the chat and open the QR code reader, so customers book or register without creating an account.
Should I build a LIFF app or a LINE MINI App?
For a new app, LINE recommends a LINE MINI App: it uses the same LIFF SDK and code, and can be verified for extra reach. Plain LIFF still makes sense if you need a LIFF-only feature such as a half-height (Compact or Tall) window or several LIFF apps on one channel.
Can I trust the user ID that liff.getProfile() returns?
Only for display in the page. Anything your server sends to the browser, or the browser sends back, can be changed. Send the ID token from liff.getIDToken() to your server and verify it with LINE's verify endpoint before you link it to a customer.
Does a LIFF app work outside the LINE app?
Yes, in an external browser the customer logs in with LINE Login first. Some features, such as sending messages into the chat, work only inside LINE.