Kho hàng của một doanh nghiệp phân phối cần quét mã vạch khi nhập và xuất hàng. Quản lý muốn nhân viên quét bằng chính điện thoại cá nhân, vì máy đã có sẵn trong túi và khỏi phải mua máy cầm tay. Câu hỏi đặt ra là làm phần mềm này thành web app, PWA hay app native.
Với trường hợp này, câu trả lời ngắn là làm web app trước, rồi chỉ chuyển sang app native khi thử trên đúng các máy nhân viên đang dùng mà việc quét vẫn không ổn định. Lý do nằm ở một API cụ thể. Barcode Detection API cho phép trang web nhận diện mã vạch trong ảnh. Theo MDN, API này vẫn là công nghệ thử nghiệm và không thuộc nhóm Baseline, vì nó không chạy trên một số trình duyệt được dùng nhiều nhất. MDN liệt kê 13 định dạng mã, từ qr_code, code_128 đến ean_13 và upc_a, cùng một giá trị unknown. Một kho đang chạy khó đặt cược vào tính năng chỉ hoạt động trên một phần máy. Trước khi viết dòng mã đầu tiên, việc cần làm là quét thử trên điện thoại thật của nhân viên.
Bài này so sánh ba cách làm, đưa bảng đánh đổi, chỉ ra giới hạn của PWA trên iPhone theo tài liệu của MDN và WebKit, rồi đưa một danh sách việc để chọn theo tình huống. Mọi khái niệm, API và giới hạn lấy từ các trang nguồn mở ngày 14/10/2026, và ghi rõ nguồn ở từng đoạn. Chỗ nguồn không nói thì bài cũng không suy đoán thêm.
Các chức năng như nhập xuất, kiểm kê và cảnh báo tồn thường đã có trong phần mềm quản lý kho. Phần còn lại của câu hỏi là các chức năng đó chạy trên thiết bị nào, và nhân viên có chấp nhận cài gì lên máy hay không.

Ba cách làm phần mềm nội bộ khác nhau ở đâu
Web app là phần mềm chạy trong trình duyệt. Nhân viên mở một địa chỉ, đăng nhập rồi làm việc, không cần cài gì lên máy. Mọi thay đổi nằm trên máy chủ, nên một lần sửa là cả đội dùng bản mới. Với phần mềm nội bộ chỉ có biểu mẫu, bảng dữ liệu, duyệt đơn và báo cáo, cách này thường đủ, vì giá trị chính nằm ở dữ liệu tập trung chứ không nằm ở tính năng của máy.
PWA là web app được thêm khả năng gần giống app thường. MDN mô tả PWA là ứng dụng xây bằng công nghệ web nhưng có trải nghiệm như ứng dụng riêng trên từng nền tảng, cài được lên thiết bị và chạy được khi mất mạng. Theo hướng dẫn làm PWA có thể cài đặt của MDN, trình duyệt Chromium cần một tệp manifest có name hoặc short_name, icons với kích thước 192px và 512px, start_url và display, còn trang phải được phục vụ qua HTTPS hoặc localhost. Service worker là thành phần giúp PWA hoạt động khi mất mạng, nhưng MDN ghi rõ đây không phải điều kiện bắt buộc để cài. Khi display có giá trị standalone, ứng dụng không hiện thanh địa chỉ của trình duyệt, nên nhìn gần giống app thật.
App native được viết cho một hệ điều hành, hoặc viết bằng một bộ công cụ đa nền rồi đóng gói, và phát hành qua cửa hàng ứng dụng. Ứng dụng gọi thẳng các tính năng của hệ điều hành, và không cần chờ trình duyệt mở API tương ứng. Cái giá là phải lo hai đường phát hành nếu cần cả iPhone lẫn Android, cộng thêm tài khoản cửa hàng và bước duyệt trước khi bản mới đến tay nhân viên. Nếu chưa rõ app là gì và vì sao doanh nghiệp làm app riêng, xem thêm app là gì và vì sao doanh nghiệp cần app.

Bảng so sánh web, PWA và app native
Bảng dưới đây đối chiếu các cách làm theo tài liệu của MDN, WebKit và App Store Review Guidelines, kiểm ngày 14/10/2026. Các ô về chi phí duy trì là nhận định từ cách mỗi lựa chọn được xây dựng, không phải số đo.
| Tiêu chí | Web app | PWA | App native |
|---|---|---|---|
| Cài đặt | Không cài, mở bằng địa chỉ | Cài từ trình duyệt. Trên iOS 16.4 trở lên, cài từ menu Chia sẻ trong Safari, Chrome, Edge, Firefox hoặc Orion | Tải từ cửa hàng ứng dụng |
| Cập nhật | Sửa trên máy chủ, mọi người dùng nhận bản mới khi mở lại | Phần nội dung cập nhật như web app, nhưng có thêm việc kiểm service worker và manifest | Phát hành bản mới qua cửa hàng, sau bước duyệt |
| Truy cập thiết bị | Qua API của trình duyệt. Nhiều API còn thử nghiệm, ví dụ đọc mã vạch | Cùng API như web app. Chế độ standalone không hiện thanh của trình duyệt | Gọi trực tiếp tính năng hệ điều hành như camera, Bluetooth, máy in |
| Offline | Cần mạng để mở trang. Service worker có thể lưu tài nguyên để mở khi mất mạng | Service worker cho trải nghiệm offline, không bắt buộc. Dữ liệu chịu quy tắc của Safari về dữ liệu ghi bằng script | Dữ liệu nằm trong ứng dụng, đội kỹ thuật tự chọn cách lưu và đồng bộ |
| Phân phối | Gửi liên kết | Gửi liên kết, nhân viên tự cài | Qua cửa hàng ứng dụng, có quy định về nội dung |
| Chi phí duy trì | Một mã nguồn, một đường phát hành | Một mã nguồn, thêm việc theo dõi giới hạn từng trình duyệt | Hai đường phát hành nếu có cả iOS và Android, cộng tài khoản cửa hàng |
| Rủi ro chính | Không có mạng thì không mở được trang, trừ khi đã có bộ nhớ đệm | Trên iOS, không có nút cài tự động và có quy tắc 7 ngày với dữ liệu ghi bằng script | Có nguy cơ bị từ chối nếu chỉ là website đóng gói, và việc sửa gấp phải đi qua duyệt |
PWA trên iPhone có những giới hạn nào
Đây là chỗ dễ hiểu sai nhất khi chọn PWA cho đội kho dùng iPhone. Theo MDN, trên iOS 16.3 trở về trước, PWA chỉ cài được bằng Safari. Từ iOS 16.4, người dùng cài được từ menu Chia sẻ trong Safari, Chrome, Edge, Firefox và Orion. Cùng trang đó ghi rằng sự kiện beforeinstallprompt, cách để trang web tự hiện hộp thoại cài đặt, không được hỗ trợ trên iOS. Trang không mời được người dùng iPhone cài bằng một nút bấm. Họ phải tự tìm đến menu Chia sẻ.
Trên máy Mac, theo cùng trang MDN, Safari cài được web app bằng lệnh File > Add to Dock trên macOS Sonoma và Safari 17 trở lên. Chi tiết này không áp dụng cho điện thoại, nhưng cho thấy cách cài khác nhau theo từng nền tảng, vì vậy mỗi nhóm máy cần một bước thử riêng.

Hệ quả với kho là thế này. Máy chủ nội bộ phải có HTTPS. MDN ghi PWA phải được phục vụ qua HTTPS hoặc từ localhost, còn service worker chỉ chạy trong ngữ cảnh an toàn theo cùng nguyên tắc. Một trang nội bộ chạy HTTP thuần trong mạng kho sẽ không cài được như PWA, và cũng không có service worker để làm việc khi mất mạng.
Dữ liệu ghi lúc mất mạng và quy tắc của Safari
Service worker cho phép trang lưu tài nguyên và phản hồi khi không có mạng. MDN ghi service worker được thiết kế để tạo trải nghiệm offline hiệu quả. Với kho, câu hỏi thực tế hơn là phiếu nhập, phiếu xuất và số kiểm kê ghi lúc mất mạng được lưu ở đâu, và trình duyệt có giữ chúng cho tới lúc đồng bộ hay không.
WebKit đã nêu một quy tắc trong bài ngày 24/03/2020. Theo bài này, Safari xoá toàn bộ dữ liệu có thể ghi bằng script của một website, trong đó có IndexedDB, LocalStorage, SessionStorage và đăng ký cùng bộ nhớ đệm của service worker, nếu người dùng Safari không tương tác với site trong 7 ngày sử dụng trình duyệt. Cùng bài viết cho biết ứng dụng đã thêm vào Màn hình chính có bộ đếm số ngày sử dụng riêng, và bộ đếm này đặt lại khi người dùng thực sự dùng ứng dụng.

Quy tắc này áp dụng khi site không có tương tác của người dùng trong 7 ngày sử dụng Safari. Một trang kiểm kê chỉ mở vài lần trong tháng, và dữ liệu nháp đang chờ đồng bộ nằm trong IndexedDB, có thể rơi đúng vào trường hợp đó. Vì vậy, với phần mềm kho trên iPhone, đưa ứng dụng ra Màn hình chính là bước đáng làm, và đồng bộ dữ liệu ngay khi có mạng là việc phải làm. Các trang nguồn đã mở hôm nay không cho thấy thay đổi nào của con số 7 ngày, và bài đó đã hơn 6 năm tuổi. Vì vậy, đội kỹ thuật cần ghi rõ con số này là của bài 2020, rồi kiểm lại trên các phiên bản iOS đang dùng trước khi dựa vào nó.
Khi nào app native là lựa chọn đúng
App native đáng làm khi công việc cần một thiết bị mà trình duyệt chưa đáp ứng ổn định. Trong kho, đó có thể là máy in tem nhãn cần kết nối trực tiếp, máy quét cầm tay kết nối qua Bluetooth, hoặc camera đọc mã liên tục suốt cả ca làm việc. Với mỗi tính năng như vậy, đội kỹ thuật cần thử trên đúng máy của nhân viên trước khi chọn web, và ghi kết quả thử làm căn cứ.
Lý do thứ hai là làm việc offline dài ngày. Nếu nhân viên làm việc nhiều giờ liền ở nơi không có sóng, và dữ liệu phải nằm trên máy đến khi đồng bộ, app native cho đội kỹ thuật quyền quyết định cách lưu và đồng bộ. Cách này không phải chờ vào quy tắc lưu trữ của trình duyệt như đã nêu ở phần trên. Với iPhone, điều đó đáng cân nhắc hơn.
Lý do thứ ba là quy định của cửa hàng ứng dụng. Mục 4.2 trong App Store Review Guidelines của Apple yêu cầu app có tính năng, nội dung và giao diện vượt hơn một website được đóng gói lại. Tài liệu này cũng nói app không được chủ yếu là web clipping hay tập hợp liên kết. Nếu chỉ muốn đưa một website nội bộ vào vỏ app, cần tính trước phần riêng sẽ có gì, vì bản chỉ bọc website có nguy cơ không qua được duyệt.
Cách chọn theo tình huống
Thực hiện theo thứ tự 6 bước sau. Mỗi bước cho ra một câu trả lời được ghi lại, và khi một bước đã đủ rõ thì dừng ở đó.
- Liệt kê tính năng cần dùng trên điện thoại. Nếu chỉ có biểu mẫu, bảng dữ liệu, duyệt đơn và báo cáo, chọn web app và kết thúc tại đây.
- Tách riêng các tính năng thiết bị như camera quét mã, máy in và Bluetooth. Với mỗi tính năng, tra MDN xem API có thuộc nhóm Baseline không, và ghi rõ trình duyệt nào chưa hỗ trợ.
- Thử từng tính năng thiết bị trên đúng dòng máy nhân viên đang dùng, gồm cả iPhone và Android nếu đội có cả hai. Ghi lại kết quả và ngày thử.
- Đo số giờ mất mạng trong một ca và loại dữ liệu cần ghi lúc đó. Nếu dữ liệu phải giữ lâu trên máy, ưu tiên app native hoặc PWA có kế hoạch đồng bộ rõ ràng, và không dựa vào bộ nhớ của trình duyệt.
- Kiểm xem nhân viên có tự cài được ứng dụng không, và trên iPhone họ có tìm được menu Chia sẻ để cài hay không. Nếu một nhóm máy không cài được, giữ web app cho nhóm đó.
- Viết quyết định kèm lý do và ngày kiểm. Khi có phiên bản iOS mới, kiểm lại đúng mục đã dựa vào nguồn cũ.
Hỏi đáp
PWA chạy được trên iPhone không?
Chạy được, nhưng có giới hạn. Theo MDN, từ iOS 16.4 người dùng cài PWA được từ menu Chia sẻ trong Safari, Chrome, Edge, Firefox hoặc Orion. Trên iOS 16.3 trở về trước, chỉ Safari cài được. Trang web không tự gọi hộp thoại cài đặt trên iOS, và phần lưu dữ liệu offline chịu quy tắc 7 ngày đã nêu ở trên.
Máy chủ nội bộ có cần HTTPS không?
Có, nếu muốn cài PWA và dùng service worker. MDN ghi PWA phải được phục vụ qua HTTPS, hoặc từ localhost và 127.0.0.1 khi phát triển. Service worker cũng chỉ chạy trong ngữ cảnh an toàn, theo cùng nguyên tắc. Chứng chỉ HTTPS cho địa chỉ nội bộ cần có ngay từ đầu, vì thiếu nó thì phần cài đặt lẫn phần offline đều không dùng được.
Có cần viết hai app riêng cho iPhone và Android không?
Không bắt buộc. Một mã nguồn có thể đóng gói cho cả hai nền, nhưng bài này không so sánh các bộ công cụ đa nền, vì chưa đối chiếu nguồn cho từng bộ. Điều cần chốt trước là tính năng thiết bị nào phải chạy trên máy nào. Quy định của từng cửa hàng ứng dụng vẫn tách riêng cho mỗi nền, và việc phát hành luôn phải tính riêng cho từng bên.
Vì sao không nên bọc website vào app native cho nhanh?
Vì mục 4.2 trong App Store Review Guidelines yêu cầu app phải vượt hơn một website được đóng gói lại. Nếu app chưa có thêm tính năng nào, bọc website vào vỏ app chỉ thêm một đường phát hành. Khi cần một năng lực thiết bị thật, chẳng hạn quét mã ổn định hay in tem trực tiếp, việc viết app native mới có lý do rõ ràng.
Làm web app trước rồi chuyển sang native có mất công không?
Phần lớn việc không phải làm lại. Logic nghiệp vụ như đơn nhập, tồn kho, phân quyền và báo cáo nằm ở máy chủ thì dùng lại được cho cả web lẫn app, miễn là API đã tách khỏi giao diện ngay từ đầu. Phần giao diện và phần truy cập thiết bị thì phải viết lại. Xem thêm từ vibe coding lên hệ thống chạy thật để biết những việc cần làm trước khi đưa một bản thử ra dùng thật.
Phần mềm kho, bán hàng hay nhân sự có chung một điểm: dữ liệu nằm trên máy chủ, còn cách nhân viên chạm vào dữ liệu thì phải chọn theo thiết bị họ đang cầm. MONA Software xây phần mềm web app và ứng dụng di động theo yêu cầu, từ phân tích tính năng, thử quét mã trên đúng máy của đội, đến chọn web, PWA hay app native cho từng nhóm người dùng. Xem dịch vụ lập trình web app, lập trình ứng dụng di động, hoặc dịch vụ viết phần mềm theo yêu cầu để biết phạm vi. Nếu cần trao đổi về kho của mình, gọi hotline 1900 636 648 và nói rõ loại máy nhân viên đang dùng cùng tính năng cần quét hoặc in.




















































