Trong công nghệ phần mềm, porting là quá trình thích ứng phần mềm với mục đích đạt được một dạng thực thi nào đó trong môi trường điện toán khác (ví dụ: CPU, hệ điều hành hoặc thư viện bên thứ ba khác) với thiết kế ban đầu của một chương trình. Thuật ngữ này cũng được sử dụng khi phần mềm/phần cứng được thay đổi để làm cho chúng có thể sử dụng được trong các môi trường khác nhau. Phần mềm là có tính di động khi chi phí porting nó vào một nền tảng mới thấp hơn so với chi phí của việc viết nó từ đầu một cách đáng kể. Thuật ngữ "port" bắt nguồn từ từ Latin "portāre", có nghĩa là "mang theo". Khi mã lệnh không tương thích với một hệ điều hành hoặc kiến ​​trúc cụ thể, mã lệnh phải được "chuyển" sang hệ thống mới. Thuật ngữ này thường không được áp dụng cho quá trình điều chỉnh phần mềm để chạy với bộ nhớ ít hơn trên cùng một CPU và hệ điều hành, cũng không áp dụng cho việc viết lại mã nguồn bằng một ngôn ngữ khác (tức là chuyển đổi hoặc dịch thuật). Các nhà phát triển phần mềm thường cho rằng phần mềm mà họ viết là di động, có nghĩa là chỉ cần ít nỗ lực để thích ứng với môi trường mới. Số lượng nỗ lực thực sự cần phụ thuộc vào một số yếu tố, bao gồm mức độ khác nhau môi trường ban đầu (nền tảng nguồn) với môi trường mới (nền tảng mục tiêu), kinh nghiệm của các tác giả gốc khi biết cấu trúc ngôn ngữ lập trình và các lời gọi thư viện bên thứ ba dường như không thể di chuyển được và nỗ lực của các tác giả ban đầu chỉ sử dụng các cấu trúc di động (các cấu trúc nền tảng cụ thể thường cung cấp một giải pháp rẻ hơn). Số lượng CPU và hệ điều hành khác nhau đáng kể được sử dụng trên máy tính để bàn hiện nay nhỏ hơn nhiều so với trước đây. Sự thống trị của kiến ​​trúc x86 có nghĩa là hầu hết các phần mềm máy tính để bàn không bao giờ được chuyển đến một CPU khác. Trong cùng một thị trường, sự lựa chọn của các hệ điều hành đã được giảm xuống một cách hiệu quả thành ba: Microsoft Windows, macOS và Linux. Tuy nhiên, trong các hệ thống nhúng và thị trường di động, tính di động vẫn là một vấn đề quan trọng, với ARM là một sự thay thế được sử dụng rộng rãi. Các tiêu chuẩn quốc tế, như được ban hành bởi ISO, tạo điều kiện thuận lợi cho việc chuyển đổi bằng cách chỉ định các chi tiết của môi trường tính toán theo cách giúp giảm sự khác biệt giữa các nền tảng tuân thủ tiêu chuẩn khác nhau. Viết phần mềm nằm trong giới hạn được chỉ định bởi các tiêu chuẩn này đại diện cho một nỗ lực thực tế mặc dù không tầm thường. Việc port một chương trình như vậy giữa hai nền tảng tuân thủ tiêu chuẩn (giống như POSIX.1) có thể chỉ là vấn đề tải mã nguồn và biên dịch lại nó trên nền tảng mới. Tuy nhiên, thực tế thường thấy rằng các sửa đổi nhỏ khác nhau là bắt buộc, do sự khác biệt nền tảng tinh tế. Hầu hết các tiêu chuẩn bị "vùng xám" nơi khác biệt trong việc giải thích các tiêu chuẩn dẫn đến các biến thể nhỏ từ nền tảng đến nền tảng. Ngoài ra, còn có một số công cụ hỗ trợ chuyển đổi, chẳng hạn như GNU Compiler Collection, cung cấp các ngôn ngữ lập trình nhất quán trên các nền tảng khác nhau, và Autotools, tự động phát hiện các biến thể nhỏ trong môi trường và điều chỉnh phần mềm tương ứng trước khi biên dịch. Các trình biên dịch cho một số ngôn ngữ lập trình bậc cao (e.g. Eiffel, Esterel) có được tính di động bằng cách xuất mã nguồn ở một ngôn ngữ trung gian bậc cao khác (giống như C) mà trình biên dịch cho nhiều nền tảng thường có sẵn. Hai hoạt động liên quan đến (nhưng khác biệt) porting là mô phỏng và biên dịch chéo. Thay vì dịch trực tiếp sang mã máy, các trình biên dịch hiện đại dịch sang một mã trung gian độc lập của máy để tăng cường tính di động của trình biên dịch và giảm thiểu các nỗ lực thiết kế. Ngôn ngữ trung gian định nghĩa một máy ảo có thể thực thi tất cả các chương trình được viết bằng ngôn ngữ trung gian (một máy được định nghĩa bằng ngôn ngữ của nó và ngược lại). Các hướng dẫn mã trung gian được dịch thành các chuỗi mã máy tương đương bằng trình tạo mã để tạo mã thực thi. Nó cũng có thể bỏ qua việc tạo mã máy bằng cách thực sự thực hiện một trình thông dịch hoặc JIT cho máy ảo. Việc sử dụng mã trung gian tăng cường tính di động của trình biên dịch, vì chỉ có mã phụ thuộc máy (trình thông dịch hoặc trình tạo mã) của trình biên dịch cần được port đến máy đích. Phần còn lại của trình biên dịch có thể được nhập dưới dạng mã trung gian và sau đó được xử lý thêm bởi trình tạo mã hoặc trình thông dịch được mã hóa, do đó tạo phần mềm biên dịch hoặc thực thi trực tiếp mã trung gian trên trình thông dịch. Phần độc lập của máy có thể được phát triển và thử nghiệm trên một máy khác ("host machine"). Điều này làm giảm đáng kể các nỗ lực thiết kế, bởi vì phần máy độc lập cần được phát triển chỉ một lần để tạo mã trung gian di động. Một trình thông dịch kém phức tạp hơn và do đó dễ dàng port hơn so với trình tạo mã, vì nó không thể thực hiện tối ưu hóa mã do chế độ xem mã chương trình bị giới hạn (nó chỉ thấy một lệnh tại một thời điểm và bạn cần một chuỗi để thực hiện tối ưu hóa). Một số trình thông dịch cực kỳ dễ dàng để port, bởi vì chúng chỉ đưa ra giả định tối thiểu về tập lệnh của phần cứng cơ bản. Kết quả là, máy ảo thậm chí còn đơn giản hơn so với CPU mục tiêu. Viết các nguồn trình biên dịch hoàn toàn bằng ngôn ngữ lập trình mà trình biên dịch có nghĩa vụ dịch, tạo ra cách tiếp cận sau, tốt hơn được gọi là trình biên dịch bootstrapping, khả thi trên máy đích: Phần khó khăn của việc viết mã các thói quen tối ưu hóa được thực hiện bằng cách sử dụng ngôn ngữ cấp cao thay vì ngôn ngữ assembly của mục tiêu. Theo các nhà thiết kế ngôn ngữ BCPL, mã giải thích (trong trường hợp BCPL) nhỏ gọn hơn mã máy; điển hình là từ 2 đến 1. Mã giải thích tuy nhiên chạy chậm hơn khoảng 10 lần so với mã được biên dịch trên cùng một máy. Các nhà thiết kế ngôn ngữ lập trình Java cố gắng tận dụng lợi thế của sự nhỏ gọn của mã giải nghĩa, bởi vì một chương trình Java có thể cần được truyền qua Internet trước khi thực thi có thể bắt đầu trên Java Virtual Machine đích.